1/* 2 * lib/route/cls/ematch/cmp.c Simple packet data comparison ematch 3 * 4 * This library is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Lesser General Public 6 * License as published by the Free Software Foundation version 2.1 7 * of the License. 8 * 9 * Copyright (c) 2008-2009 Thomas Graf <tgraf@suug.ch> 10 */ 11 12/** 13 * @ingroup ematch 14 * @defgroup em_cmp Simple packet data comparison 15 * 16 * @{ 17 */ 18 19#include <netlink-local.h> 20#include <netlink-tc.h> 21#include <netlink/netlink.h> 22#include <netlink/route/cls/ematch.h> 23#include <linux/tc_ematch/tc_em_cmp.h> 24 25void rtnl_ematch_cmp_set(struct rtnl_ematch *ematch, 26 struct tcf_em_cmp *cfg) 27{ 28 memcpy(rtnl_ematch_data(ematch), cfg, sizeof(*cfg)); 29} 30 31struct tcf_em_cmp *rtnl_ematch_cmp_get(struct rtnl_ematch *ematch) 32{ 33 return rtnl_ematch_data(ematch); 34} 35 36static const char *align_txt(struct tcf_em_cmp *cmp) 37{ 38 switch (cmp->align) { 39 case TCF_EM_ALIGN_U8: 40 return "u8"; 41 case TCF_EM_ALIGN_U16: 42 return (cmp->flags & TCF_EM_CMP_TRANS) ? "h16" : "u16"; 43 case TCF_EM_ALIGN_U32: 44 return (cmp->flags & TCF_EM_CMP_TRANS) ? "h32" : "u32"; 45 default: 46 return (cmp->flags & TCF_EM_CMP_TRANS) ? "h?" : "u?"; 47 } 48} 49 50static const char *layer_txt(struct tcf_em_cmp *cmp) 51{ 52 switch (cmp->layer) { 53 case TCF_LAYER_LINK: 54 return "link"; 55 case TCF_LAYER_NETWORK: 56 return "network"; 57 case TCF_LAYER_TRANSPORT: 58 return "transport"; 59 default: 60 return "?"; 61 } 62} 63 64static const char *relation_txt(struct tcf_em_cmp *cmp) 65{ 66 switch (cmp->opnd) { 67 case TCF_EM_OPND_EQ: 68 return "eq"; 69 case TCF_EM_OPND_LT: 70 return "lt"; 71 case TCF_EM_OPND_GT: 72 return "gt"; 73 default: 74 return "?"; 75 } 76} 77 78static int cmp_parse(struct rtnl_ematch *m, void *data, size_t len) 79{ 80 memcpy(rtnl_ematch_data(m), data, len); 81 82 return 0; 83} 84 85static void cmp_dump(struct rtnl_ematch *m, struct nl_dump_params *p) 86{ 87 struct tcf_em_cmp *cmp = rtnl_ematch_data(m); 88 89 nl_dump(p, "%s at %s+%u ", 90 align_txt(cmp), layer_txt(cmp), cmp->off); 91 92 if (cmp->mask) 93 nl_dump(p, "& 0x%x ", cmp->mask); 94 95 nl_dump(p, "%s %u", relation_txt(cmp), cmp->val); 96} 97 98static struct rtnl_ematch_ops cmp_ops = { 99 .eo_kind = TCF_EM_CMP, 100 .eo_name = "cmp", 101 .eo_datalen = sizeof(struct tcf_em_cmp), 102 .eo_parse = cmp_parse, 103 .eo_dump = cmp_dump, 104}; 105 106static void __init cmp_init(void) 107{ 108 rtnl_ematch_register(&cmp_ops); 109} 110 111static void __exit cmp_exit(void) 112{ 113 rtnl_ematch_unregister(&cmp_ops); 114} 115 116/** @} */ 117