• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * lib/route/cls/ematch/cmp.c	Simple packet data comparison ematch
3  *
4  *	This library is free software; you can redistribute it and/or
5  *	modify it under the terms of the GNU Lesser General Public
6  *	License as published by the Free Software Foundation version 2.1
7  *	of the License.
8  *
9  * Copyright (c) 2008-2009 Thomas Graf <tgraf@suug.ch>
10  */
11 
12 /**
13  * @ingroup ematch
14  * @defgroup em_cmp Simple packet data comparison
15  *
16  * @{
17  */
18 
19 #include <netlink-local.h>
20 #include <netlink-tc.h>
21 #include <netlink/netlink.h>
22 #include <netlink/route/cls/ematch.h>
23 #include <linux/tc_ematch/tc_em_cmp.h>
24 
rtnl_ematch_cmp_set(struct rtnl_ematch * ematch,struct tcf_em_cmp * cfg)25 void rtnl_ematch_cmp_set(struct rtnl_ematch *ematch,
26 			 struct tcf_em_cmp *cfg)
27 {
28 	memcpy(rtnl_ematch_data(ematch), cfg, sizeof(*cfg));
29 }
30 
rtnl_ematch_cmp_get(struct rtnl_ematch * ematch)31 struct tcf_em_cmp *rtnl_ematch_cmp_get(struct rtnl_ematch *ematch)
32 {
33 	return rtnl_ematch_data(ematch);
34 }
35 
align_txt(struct tcf_em_cmp * cmp)36 static const char *align_txt(struct tcf_em_cmp *cmp)
37 {
38 	switch (cmp->align) {
39 	case TCF_EM_ALIGN_U8:
40 		return "u8";
41 	case TCF_EM_ALIGN_U16:
42 		return (cmp->flags & TCF_EM_CMP_TRANS) ? "h16" : "u16";
43 	case TCF_EM_ALIGN_U32:
44 		return (cmp->flags & TCF_EM_CMP_TRANS) ? "h32" : "u32";
45 	default:
46 		return (cmp->flags & TCF_EM_CMP_TRANS) ? "h?" : "u?";
47 	}
48 }
49 
layer_txt(struct tcf_em_cmp * cmp)50 static const char *layer_txt(struct tcf_em_cmp *cmp)
51 {
52 	switch (cmp->layer) {
53 	case TCF_LAYER_LINK:
54 		return "link";
55 	case TCF_LAYER_NETWORK:
56 		return "network";
57 	case TCF_LAYER_TRANSPORT:
58 		return "transport";
59 	default:
60 		return "?";
61 	}
62 }
63 
relation_txt(struct tcf_em_cmp * cmp)64 static const char *relation_txt(struct tcf_em_cmp *cmp)
65 {
66 	switch (cmp->opnd) {
67 	case TCF_EM_OPND_EQ:
68 		return "eq";
69 	case TCF_EM_OPND_LT:
70 		return "lt";
71 	case TCF_EM_OPND_GT:
72 		return "gt";
73 	default:
74 		return "?";
75 	}
76 }
77 
cmp_parse(struct rtnl_ematch * m,void * data,size_t len)78 static int cmp_parse(struct rtnl_ematch *m, void *data, size_t len)
79 {
80 	memcpy(rtnl_ematch_data(m), data, len);
81 
82 	return 0;
83 }
84 
cmp_dump(struct rtnl_ematch * m,struct nl_dump_params * p)85 static void cmp_dump(struct rtnl_ematch *m, struct nl_dump_params *p)
86 {
87 	struct tcf_em_cmp *cmp = rtnl_ematch_data(m);
88 
89 	nl_dump(p, "%s at %s+%u ",
90 		align_txt(cmp), layer_txt(cmp), cmp->off);
91 
92 	if (cmp->mask)
93 		nl_dump(p, "& 0x%x ", cmp->mask);
94 
95 	nl_dump(p, "%s %u", relation_txt(cmp), cmp->val);
96 }
97 
98 static struct rtnl_ematch_ops cmp_ops = {
99 	.eo_kind	= TCF_EM_CMP,
100 	.eo_name	= "cmp",
101 	.eo_datalen	= sizeof(struct tcf_em_cmp),
102 	.eo_parse	= cmp_parse,
103 	.eo_dump	= cmp_dump,
104 };
105 
cmp_init(void)106 static void __init cmp_init(void)
107 {
108 	rtnl_ematch_register(&cmp_ops);
109 }
110 
cmp_exit(void)111 static void __exit cmp_exit(void)
112 {
113 	rtnl_ematch_unregister(&cmp_ops);
114 }
115 
116 /** @} */
117