1*4dc78e53SAndroid Build Coastguard Worker /* SPDX-License-Identifier: LGPL-2.1-only */
2*4dc78e53SAndroid Build Coastguard Worker /*
3*4dc78e53SAndroid Build Coastguard Worker * Copyright (c) 2010-2013 Thomas Graf <[email protected]>
4*4dc78e53SAndroid Build Coastguard Worker */
5*4dc78e53SAndroid Build Coastguard Worker
6*4dc78e53SAndroid Build Coastguard Worker /**
7*4dc78e53SAndroid Build Coastguard Worker * @ingroup ematch
8*4dc78e53SAndroid Build Coastguard Worker * @defgroup em_nbyte N-Byte Comparison
9*4dc78e53SAndroid Build Coastguard Worker *
10*4dc78e53SAndroid Build Coastguard Worker * @{
11*4dc78e53SAndroid Build Coastguard Worker */
12*4dc78e53SAndroid Build Coastguard Worker
13*4dc78e53SAndroid Build Coastguard Worker #include "nl-default.h"
14*4dc78e53SAndroid Build Coastguard Worker
15*4dc78e53SAndroid Build Coastguard Worker #include <linux/tc_ematch/tc_em_nbyte.h>
16*4dc78e53SAndroid Build Coastguard Worker
17*4dc78e53SAndroid Build Coastguard Worker #include <netlink/netlink.h>
18*4dc78e53SAndroid Build Coastguard Worker #include <netlink/route/cls/ematch.h>
19*4dc78e53SAndroid Build Coastguard Worker #include <netlink/route/cls/ematch/nbyte.h>
20*4dc78e53SAndroid Build Coastguard Worker
21*4dc78e53SAndroid Build Coastguard Worker struct nbyte_data
22*4dc78e53SAndroid Build Coastguard Worker {
23*4dc78e53SAndroid Build Coastguard Worker struct tcf_em_nbyte cfg;
24*4dc78e53SAndroid Build Coastguard Worker uint8_t * pattern;
25*4dc78e53SAndroid Build Coastguard Worker };
26*4dc78e53SAndroid Build Coastguard Worker
rtnl_ematch_nbyte_set_offset(struct rtnl_ematch * e,uint8_t layer,uint16_t offset)27*4dc78e53SAndroid Build Coastguard Worker void rtnl_ematch_nbyte_set_offset(struct rtnl_ematch *e, uint8_t layer,
28*4dc78e53SAndroid Build Coastguard Worker uint16_t offset)
29*4dc78e53SAndroid Build Coastguard Worker {
30*4dc78e53SAndroid Build Coastguard Worker struct nbyte_data *n = rtnl_ematch_data(e);
31*4dc78e53SAndroid Build Coastguard Worker n->cfg.off = offset;
32*4dc78e53SAndroid Build Coastguard Worker n->cfg.layer = layer;
33*4dc78e53SAndroid Build Coastguard Worker }
34*4dc78e53SAndroid Build Coastguard Worker
rtnl_ematch_nbyte_get_offset(struct rtnl_ematch * e)35*4dc78e53SAndroid Build Coastguard Worker uint16_t rtnl_ematch_nbyte_get_offset(struct rtnl_ematch *e)
36*4dc78e53SAndroid Build Coastguard Worker {
37*4dc78e53SAndroid Build Coastguard Worker return ((struct nbyte_data *) rtnl_ematch_data(e))->cfg.off;
38*4dc78e53SAndroid Build Coastguard Worker }
39*4dc78e53SAndroid Build Coastguard Worker
rtnl_ematch_nbyte_get_layer(struct rtnl_ematch * e)40*4dc78e53SAndroid Build Coastguard Worker uint8_t rtnl_ematch_nbyte_get_layer(struct rtnl_ematch *e)
41*4dc78e53SAndroid Build Coastguard Worker {
42*4dc78e53SAndroid Build Coastguard Worker return ((struct nbyte_data *) rtnl_ematch_data(e))->cfg.layer;
43*4dc78e53SAndroid Build Coastguard Worker }
44*4dc78e53SAndroid Build Coastguard Worker
rtnl_ematch_nbyte_set_pattern(struct rtnl_ematch * e,uint8_t * pattern,size_t len)45*4dc78e53SAndroid Build Coastguard Worker void rtnl_ematch_nbyte_set_pattern(struct rtnl_ematch *e,
46*4dc78e53SAndroid Build Coastguard Worker uint8_t *pattern, size_t len)
47*4dc78e53SAndroid Build Coastguard Worker {
48*4dc78e53SAndroid Build Coastguard Worker struct nbyte_data *n = rtnl_ematch_data(e);
49*4dc78e53SAndroid Build Coastguard Worker
50*4dc78e53SAndroid Build Coastguard Worker if (n->pattern)
51*4dc78e53SAndroid Build Coastguard Worker free(n->pattern);
52*4dc78e53SAndroid Build Coastguard Worker
53*4dc78e53SAndroid Build Coastguard Worker n->pattern = pattern;
54*4dc78e53SAndroid Build Coastguard Worker n->cfg.len = len;
55*4dc78e53SAndroid Build Coastguard Worker }
56*4dc78e53SAndroid Build Coastguard Worker
rtnl_ematch_nbyte_get_pattern(struct rtnl_ematch * e)57*4dc78e53SAndroid Build Coastguard Worker uint8_t *rtnl_ematch_nbyte_get_pattern(struct rtnl_ematch *e)
58*4dc78e53SAndroid Build Coastguard Worker {
59*4dc78e53SAndroid Build Coastguard Worker return ((struct nbyte_data *) rtnl_ematch_data(e))->pattern;
60*4dc78e53SAndroid Build Coastguard Worker }
61*4dc78e53SAndroid Build Coastguard Worker
rtnl_ematch_nbyte_get_len(struct rtnl_ematch * e)62*4dc78e53SAndroid Build Coastguard Worker size_t rtnl_ematch_nbyte_get_len(struct rtnl_ematch *e)
63*4dc78e53SAndroid Build Coastguard Worker {
64*4dc78e53SAndroid Build Coastguard Worker return ((struct nbyte_data *) rtnl_ematch_data(e))->cfg.len;
65*4dc78e53SAndroid Build Coastguard Worker }
66*4dc78e53SAndroid Build Coastguard Worker
layer_txt(struct tcf_em_nbyte * nbyte)67*4dc78e53SAndroid Build Coastguard Worker static const char *layer_txt(struct tcf_em_nbyte *nbyte)
68*4dc78e53SAndroid Build Coastguard Worker {
69*4dc78e53SAndroid Build Coastguard Worker switch (nbyte->layer) {
70*4dc78e53SAndroid Build Coastguard Worker case TCF_LAYER_LINK:
71*4dc78e53SAndroid Build Coastguard Worker return "link";
72*4dc78e53SAndroid Build Coastguard Worker case TCF_LAYER_NETWORK:
73*4dc78e53SAndroid Build Coastguard Worker return "net";
74*4dc78e53SAndroid Build Coastguard Worker case TCF_LAYER_TRANSPORT:
75*4dc78e53SAndroid Build Coastguard Worker return "trans";
76*4dc78e53SAndroid Build Coastguard Worker default:
77*4dc78e53SAndroid Build Coastguard Worker return "?";
78*4dc78e53SAndroid Build Coastguard Worker }
79*4dc78e53SAndroid Build Coastguard Worker }
80*4dc78e53SAndroid Build Coastguard Worker
nbyte_parse(struct rtnl_ematch * e,void * data,size_t len)81*4dc78e53SAndroid Build Coastguard Worker static int nbyte_parse(struct rtnl_ematch *e, void *data, size_t len)
82*4dc78e53SAndroid Build Coastguard Worker {
83*4dc78e53SAndroid Build Coastguard Worker struct nbyte_data *n = rtnl_ematch_data(e);
84*4dc78e53SAndroid Build Coastguard Worker size_t hdrlen = sizeof(struct tcf_em_nbyte);
85*4dc78e53SAndroid Build Coastguard Worker size_t plen = len - hdrlen;
86*4dc78e53SAndroid Build Coastguard Worker
87*4dc78e53SAndroid Build Coastguard Worker memcpy(&n->cfg, data, hdrlen);
88*4dc78e53SAndroid Build Coastguard Worker if (plen > 0) {
89*4dc78e53SAndroid Build Coastguard Worker if (!(n->pattern = calloc(1, plen)))
90*4dc78e53SAndroid Build Coastguard Worker return -NLE_NOMEM;
91*4dc78e53SAndroid Build Coastguard Worker
92*4dc78e53SAndroid Build Coastguard Worker memcpy(n->pattern, (char *) data + hdrlen, plen);
93*4dc78e53SAndroid Build Coastguard Worker }
94*4dc78e53SAndroid Build Coastguard Worker
95*4dc78e53SAndroid Build Coastguard Worker return 0;
96*4dc78e53SAndroid Build Coastguard Worker }
97*4dc78e53SAndroid Build Coastguard Worker
nbyte_dump(struct rtnl_ematch * e,struct nl_dump_params * p)98*4dc78e53SAndroid Build Coastguard Worker static void nbyte_dump(struct rtnl_ematch *e, struct nl_dump_params *p)
99*4dc78e53SAndroid Build Coastguard Worker {
100*4dc78e53SAndroid Build Coastguard Worker struct nbyte_data *n = rtnl_ematch_data(e);
101*4dc78e53SAndroid Build Coastguard Worker int i;
102*4dc78e53SAndroid Build Coastguard Worker
103*4dc78e53SAndroid Build Coastguard Worker nl_dump(p, "pattern(%u:[", n->cfg.len);
104*4dc78e53SAndroid Build Coastguard Worker
105*4dc78e53SAndroid Build Coastguard Worker for (i = 0; i < n->cfg.len; i++) {
106*4dc78e53SAndroid Build Coastguard Worker nl_dump(p, "%02x", n->pattern[i]);
107*4dc78e53SAndroid Build Coastguard Worker if (i+1 < n->cfg.len)
108*4dc78e53SAndroid Build Coastguard Worker nl_dump(p, " ");
109*4dc78e53SAndroid Build Coastguard Worker }
110*4dc78e53SAndroid Build Coastguard Worker
111*4dc78e53SAndroid Build Coastguard Worker nl_dump(p, "] at %s+%u)", layer_txt(&n->cfg), n->cfg.off);
112*4dc78e53SAndroid Build Coastguard Worker }
113*4dc78e53SAndroid Build Coastguard Worker
nbyte_free(struct rtnl_ematch * e)114*4dc78e53SAndroid Build Coastguard Worker static void nbyte_free(struct rtnl_ematch *e)
115*4dc78e53SAndroid Build Coastguard Worker {
116*4dc78e53SAndroid Build Coastguard Worker struct nbyte_data *n = rtnl_ematch_data(e);
117*4dc78e53SAndroid Build Coastguard Worker free(n->pattern);
118*4dc78e53SAndroid Build Coastguard Worker }
119*4dc78e53SAndroid Build Coastguard Worker
120*4dc78e53SAndroid Build Coastguard Worker static struct rtnl_ematch_ops nbyte_ops = {
121*4dc78e53SAndroid Build Coastguard Worker .eo_kind = TCF_EM_NBYTE,
122*4dc78e53SAndroid Build Coastguard Worker .eo_name = "nbyte",
123*4dc78e53SAndroid Build Coastguard Worker .eo_minlen = sizeof(struct tcf_em_nbyte),
124*4dc78e53SAndroid Build Coastguard Worker .eo_datalen = sizeof(struct nbyte_data),
125*4dc78e53SAndroid Build Coastguard Worker .eo_parse = nbyte_parse,
126*4dc78e53SAndroid Build Coastguard Worker .eo_dump = nbyte_dump,
127*4dc78e53SAndroid Build Coastguard Worker .eo_free = nbyte_free,
128*4dc78e53SAndroid Build Coastguard Worker };
129*4dc78e53SAndroid Build Coastguard Worker
nbyte_init(void)130*4dc78e53SAndroid Build Coastguard Worker static void _nl_init nbyte_init(void)
131*4dc78e53SAndroid Build Coastguard Worker {
132*4dc78e53SAndroid Build Coastguard Worker rtnl_ematch_register(&nbyte_ops);
133*4dc78e53SAndroid Build Coastguard Worker }
134*4dc78e53SAndroid Build Coastguard Worker
135*4dc78e53SAndroid Build Coastguard Worker /** @} */
136