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 *ematch,
00026 struct tcf_em_cmp *cfg)
00027 {
00028 memcpy(rtnl_ematch_data(ematch), cfg, sizeof(*cfg));
00029 }
00030
00031 struct tcf_em_cmp *rtnl_ematch_cmp_get(struct rtnl_ematch *ematch)
00032 {
00033 return rtnl_ematch_data(ematch);
00034 }
00035
00036 static const char *align_txt(struct tcf_em_cmp *cmp)
00037 {
00038 switch (cmp->align) {
00039 case TCF_EM_ALIGN_U8:
00040 return "u8";
00041 case TCF_EM_ALIGN_U16:
00042 return (cmp->flags & TCF_EM_CMP_TRANS) ? "h16" : "u16";
00043 case TCF_EM_ALIGN_U32:
00044 return (cmp->flags & TCF_EM_CMP_TRANS) ? "h32" : "u32";
00045 default:
00046 return (cmp->flags & TCF_EM_CMP_TRANS) ? "h?" : "u?";
00047 }
00048 }
00049
00050 static const char *layer_txt(struct tcf_em_cmp *cmp)
00051 {
00052 switch (cmp->layer) {
00053 case TCF_LAYER_LINK:
00054 return "link";
00055 case TCF_LAYER_NETWORK:
00056 return "network";
00057 case TCF_LAYER_TRANSPORT:
00058 return "transport";
00059 default:
00060 return "?";
00061 }
00062 }
00063
00064 static const char *relation_txt(struct tcf_em_cmp *cmp)
00065 {
00066 switch (cmp->opnd) {
00067 case TCF_EM_OPND_EQ:
00068 return "eq";
00069 case TCF_EM_OPND_LT:
00070 return "lt";
00071 case TCF_EM_OPND_GT:
00072 return "gt";
00073 default:
00074 return "?";
00075 }
00076 }
00077
00078 static int cmp_parse(struct rtnl_ematch *m, void *data, size_t len)
00079 {
00080 memcpy(rtnl_ematch_data(m), data, len);
00081
00082 return 0;
00083 }
00084
00085 static void cmp_dump(struct rtnl_ematch *m, struct nl_dump_params *p)
00086 {
00087 struct tcf_em_cmp *cmp = rtnl_ematch_data(m);
00088
00089 nl_dump(p, "%s at %s+%u ",
00090 align_txt(cmp), layer_txt(cmp), cmp->off);
00091
00092 if (cmp->mask)
00093 nl_dump(p, "& 0x%x ", cmp->mask);
00094
00095 nl_dump(p, "%s %u", relation_txt(cmp), cmp->val);
00096 }
00097
00098 static struct rtnl_ematch_ops cmp_ops = {
00099 .eo_kind = TCF_EM_CMP,
00100 .eo_name = "cmp",
00101 .eo_datalen = sizeof(struct tcf_em_cmp),
00102 .eo_parse = cmp_parse,
00103 .eo_dump = cmp_dump,
00104 };
00105
00106 static void __init cmp_init(void)
00107 {
00108 rtnl_ematch_register(&cmp_ops);
00109 }
00110
00111 static void __exit cmp_exit(void)
00112 {
00113 rtnl_ematch_unregister(&cmp_ops);
00114 }
00115
00116