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