libnl 2.0
|
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 /** @} */