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@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
25void 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
30struct tcf_em_cmp *rtnl_ematch_cmp_get(struct rtnl_ematch *e)
31{
32	return rtnl_ematch_data(e);
33}
34
35static 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
42static const char *align_txt[] = {
43	[TCF_EM_ALIGN_U8] = "u8",
44	[TCF_EM_ALIGN_U16] = "u16",
45	[TCF_EM_ALIGN_U32] = "u32"
46};
47
48static const char *layer_txt[] = {
49	[TCF_LAYER_LINK] = "eth",
50	[TCF_LAYER_NETWORK] = "ip",
51	[TCF_LAYER_TRANSPORT] = "tcp"
52};
53
54static const char *operand_txt[] = {
55	[TCF_EM_OPND_EQ] = "=",
56	[TCF_EM_OPND_LT] = "<",
57	[TCF_EM_OPND_GT] = ">",
58};
59
60static 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
79static 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
88static void __init cmp_init(void)
89{
90	rtnl_ematch_register(&cmp_ops);
91}
92
93/** @} */
94