• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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