libnl 3.7.0
text.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_text Text Search
9 *
10 * @{
11 */
12
13#include <netlink-private/netlink.h>
14#include <netlink-private/utils.h>
15#include <netlink-private/tc.h>
16#include <netlink/netlink.h>
17#include <netlink/route/cls/ematch.h>
18#include <netlink/route/cls/ematch/text.h>
19#include <linux/tc_ematch/tc_em_text.h>
20
22{
23 struct tcf_em_text cfg;
24 char * pattern;
25};
26
27void rtnl_ematch_text_set_from(struct rtnl_ematch *e, uint8_t layer,
28 uint16_t offset)
29{
30 struct text_data *t = rtnl_ematch_data(e);
31 t->cfg.from_offset = offset;
32 t->cfg.from_layer = layer;
33}
34
35uint16_t rtnl_ematch_text_get_from_offset(struct rtnl_ematch *e)
36{
37 return ((struct text_data *) rtnl_ematch_data(e))->cfg.from_offset;
38}
39
40uint8_t rtnl_ematch_text_get_from_layer(struct rtnl_ematch *e)
41{
42 return ((struct text_data *) rtnl_ematch_data(e))->cfg.from_layer;
43}
44
45void rtnl_ematch_text_set_to(struct rtnl_ematch *e, uint8_t layer,
46 uint16_t offset)
47{
48 struct text_data *t = rtnl_ematch_data(e);
49 t->cfg.to_offset = offset;
50 t->cfg.to_layer = layer;
51}
52
53uint16_t rtnl_ematch_text_get_to_offset(struct rtnl_ematch *e)
54{
55 return ((struct text_data *) rtnl_ematch_data(e))->cfg.to_offset;
56}
57
58uint8_t rtnl_ematch_text_get_to_layer(struct rtnl_ematch *e)
59{
60 return ((struct text_data *) rtnl_ematch_data(e))->cfg.to_layer;
61}
62
63void rtnl_ematch_text_set_pattern(struct rtnl_ematch *e,
64 char *pattern, size_t len)
65{
66 struct text_data *t = rtnl_ematch_data(e);
67
68 if (t->pattern)
69 free(t->pattern);
70
71 t->pattern = pattern;
72 t->cfg.pattern_len = len;
73}
74
75char *rtnl_ematch_text_get_pattern(struct rtnl_ematch *e)
76{
77 return ((struct text_data *) rtnl_ematch_data(e))->pattern;
78}
79
80size_t rtnl_ematch_text_get_len(struct rtnl_ematch *e)
81{
82 return ((struct text_data *) rtnl_ematch_data(e))->cfg.pattern_len;
83}
84
85void rtnl_ematch_text_set_algo(struct rtnl_ematch *e, const char *algo)
86{
87 struct text_data *t = rtnl_ematch_data(e);
88
89 _nl_strncpy_trunc(t->cfg.algo, algo, sizeof(t->cfg.algo));
90}
91
92char *rtnl_ematch_text_get_algo(struct rtnl_ematch *e)
93{
94 struct text_data *t = rtnl_ematch_data(e);
95
96 return t->cfg.algo[0] ? t->cfg.algo : NULL;
97}
98
99static int text_parse(struct rtnl_ematch *e, void *data, size_t len)
100{
101 struct text_data *t = rtnl_ematch_data(e);
102 size_t hdrlen = sizeof(struct tcf_em_text);
103 size_t plen = len - hdrlen;
104
105 memcpy(&t->cfg, data, hdrlen);
106
107 if (t->cfg.pattern_len > plen)
108 return -NLE_INVAL;
109
110 if (t->cfg.pattern_len > 0) {
111 if (!(t->pattern = calloc(1, t->cfg.pattern_len)))
112 return -NLE_NOMEM;
113
114 memcpy(t->pattern, (char *) data + hdrlen, t->cfg.pattern_len);
115 }
116
117 return 0;
118}
119
120static void text_dump(struct rtnl_ematch *e, struct nl_dump_params *p)
121{
122 struct text_data *t = rtnl_ematch_data(e);
123 char buf[64];
124
125 nl_dump(p, "text(%s \"%s\"",
126 t->cfg.algo[0] ? t->cfg.algo : "no-algo",
127 t->pattern ? t->pattern : "no-pattern");
128
129 if (t->cfg.from_layer || t->cfg.from_offset) {
130 nl_dump(p, " from %s",
131 rtnl_ematch_offset2txt(t->cfg.from_layer,
132 t->cfg.from_offset,
133 buf, sizeof(buf)));
134 }
135
136 if (t->cfg.to_layer || t->cfg.to_offset) {
137 nl_dump(p, " to %s",
138 rtnl_ematch_offset2txt(t->cfg.to_layer,
139 t->cfg.to_offset,
140 buf, sizeof(buf)));
141 }
142
143 nl_dump(p, ")");
144}
145
146static int text_fill(struct rtnl_ematch *e, struct nl_msg *msg)
147{
148 struct text_data *t = rtnl_ematch_data(e);
149 int err;
150
151 if ((err = nlmsg_append(msg, &t->cfg, sizeof(t->cfg), 0)) < 0)
152 return err;
153
154 return nlmsg_append(msg, t->pattern, t->cfg.pattern_len, 0);
155}
156
157static void text_free(struct rtnl_ematch *e)
158{
159 struct text_data *t = rtnl_ematch_data(e);
160 free(t->pattern);
161}
162
163static struct rtnl_ematch_ops text_ops = {
164 .eo_kind = TCF_EM_TEXT,
165 .eo_name = "text",
166 .eo_minlen = sizeof(struct tcf_em_text),
167 .eo_datalen = sizeof(struct text_data),
168 .eo_parse = text_parse,
169 .eo_dump = text_dump,
170 .eo_fill = text_fill,
171 .eo_free = text_free,
172};
173
174static void __init text_init(void)
175{
176 rtnl_ematch_register(&text_ops);
177}
178
179/** @} */
int rtnl_ematch_register(struct rtnl_ematch_ops *ops)
Register ematch module.
Definition: ematch.c:40
int nlmsg_append(struct nl_msg *n, void *data, size_t len, int pad)
Append data to tail of a netlink message.
Definition: msg.c:442
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
Definition: text.c:22