Home | History | Annotate | Download | only in ematch
      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-2013 Thomas Graf <tgraf (at) suug.ch>
     10  */
     11 
     12 /**
     13  * @ingroup ematch
     14  * @defgroup em_cmp Simple packet data comparison
     15  *
     16  * @{
     17  */
     18 
     19 #include <netlink-private/netlink.h>
     20 #include <netlink-private/tc.h>
     21 #include <netlink/netlink.h>
     22 #include <netlink/route/cls/ematch.h>
     23 #include <linux/tc_ematch/tc_em_cmp.h>
     24 
     25 void rtnl_ematch_cmp_set(struct rtnl_ematch *e, struct tcf_em_cmp *cfg)
     26 {
     27 	memcpy(rtnl_ematch_data(e), cfg, sizeof(*cfg));
     28 }
     29 
     30 struct tcf_em_cmp *rtnl_ematch_cmp_get(struct rtnl_ematch *e)
     31 {
     32 	return rtnl_ematch_data(e);
     33 }
     34 
     35 static int cmp_parse(struct rtnl_ematch *e, void *data, size_t len)
     36 {
     37 	memcpy(rtnl_ematch_data(e), data, len);
     38 
     39 	return 0;
     40 }
     41 
     42 static const char *align_txt[] = {
     43 	[TCF_EM_ALIGN_U8] = "u8",
     44 	[TCF_EM_ALIGN_U16] = "u16",
     45 	[TCF_EM_ALIGN_U32] = "u32"
     46 };
     47 
     48 static const char *layer_txt[] = {
     49 	[TCF_LAYER_LINK] = "eth",
     50 	[TCF_LAYER_NETWORK] = "ip",
     51 	[TCF_LAYER_TRANSPORT] = "tcp"
     52 };
     53 
     54 static const char *operand_txt[] = {
     55 	[TCF_EM_OPND_EQ] = "=",
     56 	[TCF_EM_OPND_LT] = "<",
     57 	[TCF_EM_OPND_GT] = ">",
     58 };
     59 
     60 static void cmp_dump(struct rtnl_ematch *e, struct nl_dump_params *p)
     61 {
     62 	struct tcf_em_cmp *cmp = rtnl_ematch_data(e);
     63 
     64 	if (cmp->flags & TCF_EM_CMP_TRANS)
     65 		nl_dump(p, "ntoh%c(", (cmp->align == TCF_EM_ALIGN_U32) ? 'l' : 's');
     66 
     67 	nl_dump(p, "%s at %s+%u",
     68 		align_txt[cmp->align], layer_txt[cmp->layer], cmp->off);
     69 
     70 	if (cmp->mask)
     71 		nl_dump(p, " & 0x%x", cmp->mask);
     72 
     73 	if (cmp->flags & TCF_EM_CMP_TRANS)
     74 		nl_dump(p, ")");
     75 
     76 	nl_dump(p, " %s %u", operand_txt[cmp->opnd], cmp->val);
     77 }
     78 
     79 static struct rtnl_ematch_ops cmp_ops = {
     80 	.eo_kind	= TCF_EM_CMP,
     81 	.eo_name	= "cmp",
     82 	.eo_minlen	= sizeof(struct tcf_em_cmp),
     83 	.eo_datalen	= sizeof(struct tcf_em_cmp),
     84 	.eo_parse	= cmp_parse,
     85 	.eo_dump	= cmp_dump,
     86 };
     87 
     88 static void __init cmp_init(void)
     89 {
     90 	rtnl_ematch_register(&cmp_ops);
     91 }
     92 
     93 /** @} */
     94