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