libnl 2.0

/tmp/buildd/libnl2-2.0/lib/route/cls/ematch/cmp.c

00001 /*
00002  * lib/route/cls/ematch/cmp.c   Simple packet data comparison ematch
00003  *
00004  *      This library is free software; you can redistribute it and/or
00005  *      modify it under the terms of the GNU Lesser General Public
00006  *      License as published by the Free Software Foundation version 2.1
00007  *      of the License.
00008  *
00009  * Copyright (c) 2008-2009 Thomas Graf <tgraf@suug.ch>
00010  */
00011 
00012 /**
00013  * @ingroup ematch
00014  * @defgroup em_cmp Simple packet data comparison
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 /** @} */