Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/net/sched/em_cmp.c
15109 views
1
/*
2
* net/sched/em_cmp.c Simple packet data comparison ematch
3
*
4
* This program is free software; you can redistribute it and/or
5
* modify it under the terms of the GNU General Public License
6
* as published by the Free Software Foundation; either version
7
* 2 of the License, or (at your option) any later version.
8
*
9
* Authors: Thomas Graf <[email protected]>
10
*/
11
12
#include <linux/module.h>
13
#include <linux/types.h>
14
#include <linux/kernel.h>
15
#include <linux/skbuff.h>
16
#include <linux/tc_ematch/tc_em_cmp.h>
17
#include <asm/unaligned.h>
18
#include <net/pkt_cls.h>
19
20
static inline int cmp_needs_transformation(struct tcf_em_cmp *cmp)
21
{
22
return unlikely(cmp->flags & TCF_EM_CMP_TRANS);
23
}
24
25
static int em_cmp_match(struct sk_buff *skb, struct tcf_ematch *em,
26
struct tcf_pkt_info *info)
27
{
28
struct tcf_em_cmp *cmp = (struct tcf_em_cmp *) em->data;
29
unsigned char *ptr = tcf_get_base_ptr(skb, cmp->layer) + cmp->off;
30
u32 val = 0;
31
32
if (!tcf_valid_offset(skb, ptr, cmp->align))
33
return 0;
34
35
switch (cmp->align) {
36
case TCF_EM_ALIGN_U8:
37
val = *ptr;
38
break;
39
40
case TCF_EM_ALIGN_U16:
41
val = get_unaligned_be16(ptr);
42
43
if (cmp_needs_transformation(cmp))
44
val = be16_to_cpu(val);
45
break;
46
47
case TCF_EM_ALIGN_U32:
48
/* Worth checking boundries? The branching seems
49
* to get worse. Visit again.
50
*/
51
val = get_unaligned_be32(ptr);
52
53
if (cmp_needs_transformation(cmp))
54
val = be32_to_cpu(val);
55
break;
56
57
default:
58
return 0;
59
}
60
61
if (cmp->mask)
62
val &= cmp->mask;
63
64
switch (cmp->opnd) {
65
case TCF_EM_OPND_EQ:
66
return val == cmp->val;
67
case TCF_EM_OPND_LT:
68
return val < cmp->val;
69
case TCF_EM_OPND_GT:
70
return val > cmp->val;
71
}
72
73
return 0;
74
}
75
76
static struct tcf_ematch_ops em_cmp_ops = {
77
.kind = TCF_EM_CMP,
78
.datalen = sizeof(struct tcf_em_cmp),
79
.match = em_cmp_match,
80
.owner = THIS_MODULE,
81
.link = LIST_HEAD_INIT(em_cmp_ops.link)
82
};
83
84
static int __init init_em_cmp(void)
85
{
86
return tcf_em_register(&em_cmp_ops);
87
}
88
89
static void __exit exit_em_cmp(void)
90
{
91
tcf_em_unregister(&em_cmp_ops);
92
}
93
94
MODULE_LICENSE("GPL");
95
96
module_init(init_em_cmp);
97
module_exit(exit_em_cmp);
98
99
MODULE_ALIAS_TCF_EMATCH(TCF_EM_CMP);
100
101