1 /* SPDX-License-Identifier: LGPL-2.1-only */
2 /*
3 * lib/netfilter/queue_obj.c Netfilter Queue
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation version 2.1
8 * of the License.
9 *
10 * Copyright (c) 2007, 2008 Patrick McHardy <kaber@trash.net>
11 */
12
13 /**
14 * @ingroup nfnl
15 * @defgroup queue Queue
16 * @brief
17 * @{
18 */
19
20 #include <netlink-private/netlink.h>
21 #include <netlink/netfilter/nfnl.h>
22 #include <netlink/netfilter/queue.h>
23
24 /** @cond SKIP */
25 #define QUEUE_ATTR_GROUP (1UL << 0)
26 #define QUEUE_ATTR_MAXLEN (1UL << 1)
27 #define QUEUE_ATTR_COPY_MODE (1UL << 2)
28 #define QUEUE_ATTR_COPY_RANGE (1UL << 3)
29 /** @endcond */
30
31
nfnl_queue_dump(struct nl_object * a,struct nl_dump_params * p)32 static void nfnl_queue_dump(struct nl_object *a, struct nl_dump_params *p)
33 {
34 struct nfnl_queue *queue = (struct nfnl_queue *) a;
35 char buf[64];
36
37 nl_new_line(p);
38
39 if (queue->ce_mask & QUEUE_ATTR_GROUP)
40 nl_dump(p, "group=%u ", queue->queue_group);
41
42 if (queue->ce_mask & QUEUE_ATTR_MAXLEN)
43 nl_dump(p, "maxlen=%u ", queue->queue_maxlen);
44
45 if (queue->ce_mask & QUEUE_ATTR_COPY_MODE)
46 nl_dump(p, "copy_mode=%s ",
47 nfnl_queue_copy_mode2str(queue->queue_copy_mode,
48 buf, sizeof(buf)));
49
50 if (queue->ce_mask & QUEUE_ATTR_COPY_RANGE)
51 nl_dump(p, "copy_range=%u ", queue->queue_copy_range);
52
53 nl_dump(p, "\n");
54 }
55
56 static const struct trans_tbl copy_modes[] = {
57 __ADD(NFNL_QUEUE_COPY_NONE, none),
58 __ADD(NFNL_QUEUE_COPY_META, meta),
59 __ADD(NFNL_QUEUE_COPY_PACKET, packet),
60 };
61
nfnl_queue_copy_mode2str(enum nfnl_queue_copy_mode copy_mode,char * buf,size_t len)62 char *nfnl_queue_copy_mode2str(enum nfnl_queue_copy_mode copy_mode, char *buf,
63 size_t len)
64 {
65 return __type2str(copy_mode, buf, len, copy_modes,
66 ARRAY_SIZE(copy_modes));
67 }
68
nfnl_queue_str2copy_mode(const char * name)69 int nfnl_queue_str2copy_mode(const char *name)
70 {
71 return __str2type(name, copy_modes, ARRAY_SIZE(copy_modes));
72 }
73
74 /**
75 * @name Allocation/Freeing
76 * @{
77 */
78
nfnl_queue_alloc(void)79 struct nfnl_queue *nfnl_queue_alloc(void)
80 {
81 return (struct nfnl_queue *) nl_object_alloc(&queue_obj_ops);
82 }
83
nfnl_queue_get(struct nfnl_queue * queue)84 void nfnl_queue_get(struct nfnl_queue *queue)
85 {
86 nl_object_get((struct nl_object *) queue);
87 }
88
nfnl_queue_put(struct nfnl_queue * queue)89 void nfnl_queue_put(struct nfnl_queue *queue)
90 {
91 nl_object_put((struct nl_object *) queue);
92 }
93
94 /** @} */
95
96 /**
97 * @name Attributes
98 * @{
99 */
100
nfnl_queue_set_group(struct nfnl_queue * queue,uint16_t group)101 void nfnl_queue_set_group(struct nfnl_queue *queue, uint16_t group)
102 {
103 queue->queue_group = group;
104 queue->ce_mask |= QUEUE_ATTR_GROUP;
105 }
106
nfnl_queue_test_group(const struct nfnl_queue * queue)107 int nfnl_queue_test_group(const struct nfnl_queue *queue)
108 {
109 return !!(queue->ce_mask & QUEUE_ATTR_GROUP);
110 }
111
nfnl_queue_get_group(const struct nfnl_queue * queue)112 uint16_t nfnl_queue_get_group(const struct nfnl_queue *queue)
113 {
114 return queue->queue_group;
115 }
116
nfnl_queue_set_maxlen(struct nfnl_queue * queue,uint32_t maxlen)117 void nfnl_queue_set_maxlen(struct nfnl_queue *queue, uint32_t maxlen)
118 {
119 queue->queue_maxlen = maxlen;
120 queue->ce_mask |= QUEUE_ATTR_MAXLEN;
121 }
122
nfnl_queue_test_maxlen(const struct nfnl_queue * queue)123 int nfnl_queue_test_maxlen(const struct nfnl_queue *queue)
124 {
125 return !!(queue->ce_mask & QUEUE_ATTR_MAXLEN);
126 }
127
nfnl_queue_get_maxlen(const struct nfnl_queue * queue)128 uint32_t nfnl_queue_get_maxlen(const struct nfnl_queue *queue)
129 {
130 return queue->queue_maxlen;
131 }
132
nfnl_queue_set_copy_mode(struct nfnl_queue * queue,enum nfnl_queue_copy_mode mode)133 void nfnl_queue_set_copy_mode(struct nfnl_queue *queue, enum nfnl_queue_copy_mode mode)
134 {
135 queue->queue_copy_mode = mode;
136 queue->ce_mask |= QUEUE_ATTR_COPY_MODE;
137 }
138
nfnl_queue_test_copy_mode(const struct nfnl_queue * queue)139 int nfnl_queue_test_copy_mode(const struct nfnl_queue *queue)
140 {
141 return !!(queue->ce_mask & QUEUE_ATTR_COPY_MODE);
142 }
143
nfnl_queue_get_copy_mode(const struct nfnl_queue * queue)144 enum nfnl_queue_copy_mode nfnl_queue_get_copy_mode(const struct nfnl_queue *queue)
145 {
146 return queue->queue_copy_mode;
147 }
148
nfnl_queue_set_copy_range(struct nfnl_queue * queue,uint32_t copy_range)149 void nfnl_queue_set_copy_range(struct nfnl_queue *queue, uint32_t copy_range)
150 {
151 queue->queue_copy_range = copy_range;
152 queue->ce_mask |= QUEUE_ATTR_COPY_RANGE;
153 }
154
nfnl_queue_test_copy_range(const struct nfnl_queue * queue)155 int nfnl_queue_test_copy_range(const struct nfnl_queue *queue)
156 {
157 return !!(queue->ce_mask & QUEUE_ATTR_COPY_RANGE);
158 }
159
nfnl_queue_get_copy_range(const struct nfnl_queue * queue)160 uint32_t nfnl_queue_get_copy_range(const struct nfnl_queue *queue)
161 {
162 return queue->queue_copy_range;
163 }
164
nfnl_queue_compare(struct nl_object * _a,struct nl_object * _b,uint64_t attrs,int flags)165 static uint64_t nfnl_queue_compare(struct nl_object *_a, struct nl_object *_b,
166 uint64_t attrs, int flags)
167 {
168 struct nfnl_queue *a = (struct nfnl_queue *) _a;
169 struct nfnl_queue *b = (struct nfnl_queue *) _b;
170 uint64_t diff = 0;
171
172 #define NFNL_QUEUE_DIFF(ATTR, EXPR) \
173 ATTR_DIFF(attrs, QUEUE_ATTR_##ATTR, a, b, EXPR)
174 #define NFNL_QUEUE_DIFF_VAL(ATTR, FIELD) \
175 NFNL_QUEUE_DIFF(ATTR, a->FIELD != b->FIELD)
176
177 diff |= NFNL_QUEUE_DIFF_VAL(GROUP, queue_group);
178 diff |= NFNL_QUEUE_DIFF_VAL(MAXLEN, queue_maxlen);
179 diff |= NFNL_QUEUE_DIFF_VAL(COPY_MODE, queue_copy_mode);
180 diff |= NFNL_QUEUE_DIFF_VAL(COPY_RANGE, queue_copy_range);
181
182 #undef NFNL_QUEUE_DIFF
183 #undef NFNL_QUEUE_DIFF_VAL
184
185 return diff;
186 }
187
188 static const struct trans_tbl nfnl_queue_attrs[] = {
189 __ADD(QUEUE_ATTR_GROUP, group),
190 __ADD(QUEUE_ATTR_MAXLEN, maxlen),
191 __ADD(QUEUE_ATTR_COPY_MODE, copy_mode),
192 __ADD(QUEUE_ATTR_COPY_RANGE, copy_range),
193 };
194
nfnl_queue_attrs2str(int attrs,char * buf,size_t len)195 static char *nfnl_queue_attrs2str(int attrs, char *buf, size_t len)
196 {
197 return __flags2str(attrs, buf, len, nfnl_queue_attrs,
198 ARRAY_SIZE(nfnl_queue_attrs));
199 }
200
201 /** @} */
202
203 struct nl_object_ops queue_obj_ops = {
204 .oo_name = "netfilter/queue",
205 .oo_size = sizeof(struct nfnl_queue),
206 .oo_dump = {
207 [NL_DUMP_LINE] = nfnl_queue_dump,
208 [NL_DUMP_DETAILS] = nfnl_queue_dump,
209 [NL_DUMP_STATS] = nfnl_queue_dump,
210 },
211 .oo_compare = nfnl_queue_compare,
212 .oo_attrs2str = nfnl_queue_attrs2str,
213 .oo_id_attrs = QUEUE_ATTR_GROUP,
214 };
215
216 /** @} */
217