00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <netlink-local.h>
00020 #include <netlink-tc.h>
00021 #include <netlink/netlink.h>
00022 #include <netlink/route/cls/ematch.h>
00023 #include <linux/tc_ematch/tc_em_cmp.h>
00024
00025 void rtnl_ematch_cmp_set(struct rtnl_ematch *e, struct tcf_em_cmp *cfg)
00026 {
00027 memcpy(rtnl_ematch_data(e), cfg, sizeof(*cfg));
00028 }
00029
00030 struct tcf_em_cmp *rtnl_ematch_cmp_get(struct rtnl_ematch *e)
00031 {
00032 return rtnl_ematch_data(e);
00033 }
00034
00035 static int cmp_parse(struct rtnl_ematch *e, void *data, size_t len)
00036 {
00037 memcpy(rtnl_ematch_data(e), data, len);
00038
00039 return 0;
00040 }
00041
00042 static const char *align_txt[] = {
00043 [TCF_EM_ALIGN_U8] = "u8",
00044 [TCF_EM_ALIGN_U16] = "u16",
00045 [TCF_EM_ALIGN_U32] = "u32"
00046 };
00047
00048 static const char *layer_txt[] = {
00049 [TCF_LAYER_LINK] = "eth",
00050 [TCF_LAYER_NETWORK] = "ip",
00051 [TCF_LAYER_TRANSPORT] = "tcp"
00052 };
00053
00054 static const char *operand_txt[] = {
00055 [TCF_EM_OPND_EQ] = "=",
00056 [TCF_EM_OPND_LT] = "<",
00057 [TCF_EM_OPND_GT] = ">",
00058 };
00059
00060 static void cmp_dump(struct rtnl_ematch *e, struct nl_dump_params *p)
00061 {
00062 struct tcf_em_cmp *cmp = rtnl_ematch_data(e);
00063
00064 if (cmp->flags & TCF_EM_CMP_TRANS)
00065 nl_dump(p, "ntoh%c(", (cmp->align == TCF_EM_ALIGN_U32) ? 'l' : 's');
00066
00067 nl_dump(p, "%s at %s+%u",
00068 align_txt[cmp->align], layer_txt[cmp->layer], cmp->off);
00069
00070 if (cmp->mask)
00071 nl_dump(p, " & 0x%x", cmp->mask);
00072
00073 if (cmp->flags & TCF_EM_CMP_TRANS)
00074 nl_dump(p, ")");
00075
00076 nl_dump(p, " %s %u", operand_txt[cmp->opnd], cmp->val);
00077 }
00078
00079 static struct rtnl_ematch_ops cmp_ops = {
00080 .eo_kind = TCF_EM_CMP,
00081 .eo_name = "cmp",
00082 .eo_minlen = sizeof(struct tcf_em_cmp),
00083 .eo_datalen = sizeof(struct tcf_em_cmp),
00084 .eo_parse = cmp_parse,
00085 .eo_dump = cmp_dump,
00086 };
00087
00088 static void __init cmp_init(void)
00089 {
00090 rtnl_ematch_register(&cmp_ops);
00091 }
00092
00093