libnl 3.11.0
selector.c
1/* SPDX-License-Identifier: LGPL-2.1-only */
2/*
3 * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
4 *
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 *
13 * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the
16 * distribution.
17 *
18 * Neither the name of Texas Instruments Incorporated nor the names of
19 * its contributors may be used to endorse or promote products derived
20 * from this software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
26 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 *
34 */
35/**
36 * @ingroup xfrmnl
37 * @defgroup XFRM Address Selector
38 *
39 * Abstract data type representing XFRM SA/SP selector properties
40 *
41 * @{
42 *
43 * Header
44 * ------
45 * ~~~~{.c}
46 * #include <netlink/xfrm/selector.h>
47 * ~~~~
48 */
49
50#include "nl-default.h"
51
52#include <netlink/xfrm/selector.h>
53
54/* Selector, used as selector both on policy rules (SPD) and SAs. */
55struct xfrmnl_sel {
56 uint32_t refcnt;
57 struct nl_addr* daddr;
58 struct nl_addr* saddr;
59 uint16_t dport;
60 uint16_t dport_mask;
61 uint16_t sport;
62 uint16_t sport_mask;
63 uint16_t family;
64 uint8_t prefixlen_d;
65 uint8_t prefixlen_s;
66 uint8_t proto;
67 int32_t ifindex;
68 uint32_t user;
69};
70
71static void sel_destroy(struct xfrmnl_sel* sel)
72{
73 if (!sel)
74 return;
75
76 if (sel->refcnt != 1)
77 {
78 fprintf(stderr, "BUG: %s:%d\n", __FILE__, __LINE__);
79 assert(0);
80 }
81
82 nl_addr_put (sel->daddr);
83 nl_addr_put (sel->saddr);
84 free(sel);
85}
86
87/**
88 * @name Creating Selector
89 * @{
90 */
91
92/**
93 * Allocate new selector object.
94 * @return Newly allocated selector object or NULL
95 */
97{
98 struct xfrmnl_sel* sel;
99
100 sel = calloc(1, sizeof(struct xfrmnl_sel));
101 if (!sel)
102 return NULL;
103
104 sel->refcnt = 1;
105
106 return sel;
107}
108
109/**
110 * Clone existing selector object.
111 * @arg sel Selector object.
112 * @return Newly allocated selector object being a duplicate of the
113 * specified selector object or NULL if a failure occured.
114 */
116{
117 struct xfrmnl_sel* new;
118
119 new = xfrmnl_sel_alloc();
120 if (!new)
121 return NULL;
122
123 memcpy(new, sel, sizeof(struct xfrmnl_sel));
124 new->daddr = nl_addr_clone(sel->daddr);
125 new->saddr = nl_addr_clone(sel->saddr);
126
127 return new;
128}
129
130/** @} */
131
132/**
133 * @name Managing Usage References
134 * @{
135 */
136
137struct xfrmnl_sel* xfrmnl_sel_get(struct xfrmnl_sel* sel)
138{
139 sel->refcnt++;
140
141 return sel;
142}
143
144void xfrmnl_sel_put(struct xfrmnl_sel* sel)
145{
146 if (!sel)
147 return;
148
149 if (sel->refcnt == 1)
150 sel_destroy(sel);
151 else
152 sel->refcnt--;
153}
154
155/**
156 * Check whether an selector object is shared.
157 * @arg addr Selector object.
158 * @return Non-zero if the selector object is shared, otherwise 0.
159 */
161{
162 return sel->refcnt > 1;
163}
164
165/** @} */
166
167/**
168 * @name Miscellaneous
169 * @{
170 */
171
172/**
173 * Compares two selector objects.
174 * @arg a A selector object.
175 * @arg b Another selector object.
176 *
177 * @return Non zero if difference is found, 0 otherwise if both
178 * the objects are identical.
179 */
180int xfrmnl_sel_cmp(struct xfrmnl_sel* a, struct xfrmnl_sel* b)
181{
182 /* Check for any differences */
183 if ((nl_addr_cmp_prefix (a->daddr, b->daddr) != 0) ||
184 (nl_addr_cmp_prefix (a->saddr, b->saddr) != 0) ||
185 ((a->sport & a->sport_mask) != (b->sport & b->sport_mask)) ||
186 ((a->dport & a->dport_mask) != (b->dport & b->dport_mask)) ||
187 (a->family != b->family) ||
188 (a->proto && (a->proto != b->proto)) ||
189 (a->ifindex && a->ifindex != b->ifindex) ||
190 (a->user != b->user))
191 return 1;
192
193 /* The objects are identical */
194 return 0;
195}
196
197void xfrmnl_sel_dump(struct xfrmnl_sel* sel, struct nl_dump_params *p)
198{
199 char dst[INET6_ADDRSTRLEN+5], src[INET6_ADDRSTRLEN+5];
200 char buf [128];
201
202 nl_dump_line(p, "\t\tsrc %s dst %s family: %s\n", nl_addr2str(sel->saddr, src, sizeof(src)),
203 nl_addr2str (sel->daddr, dst, sizeof (dst)), nl_af2str (sel->family, buf, 128));
204 nl_dump_line (p, "\t\tsrc port/mask: %d/%d dst port/mask: %d/%d\n",
205 sel->dport, sel->dport_mask, sel->sport, sel->sport_mask);
206 nl_dump_line (p, "\t\tprotocol: %s ifindex: %u user: %u\n",
207 nl_ip_proto2str (sel->proto, buf, sizeof(buf)), sel->ifindex, sel->user);
208
209 return;
210}
211
212
213/** @} */
214
215/**
216 * @name Attributes
217 * @{
218 */
219struct nl_addr* xfrmnl_sel_get_daddr (struct xfrmnl_sel* sel)
220{
221 return sel->daddr;
222}
223
224int xfrmnl_sel_set_daddr (struct xfrmnl_sel* sel, struct nl_addr* addr)
225{
226 /* Increment reference counter on this to keep this address
227 * object around while selector in use */
228 nl_addr_get(addr);
229
230 sel->daddr = addr;
231
232 return 0;
233}
234
235struct nl_addr* xfrmnl_sel_get_saddr (struct xfrmnl_sel* sel)
236{
237 return sel->saddr;
238}
239
240int xfrmnl_sel_set_saddr (struct xfrmnl_sel* sel, struct nl_addr* addr)
241{
242 /* Increment reference counter on this to keep this address
243 * object around while selector in use */
244 nl_addr_get(addr);
245
246 sel->saddr = addr;
247
248 return 0;
249}
250
251int xfrmnl_sel_get_dport (struct xfrmnl_sel* sel)
252{
253 return sel->dport;
254}
255
256int xfrmnl_sel_set_dport (struct xfrmnl_sel* sel, unsigned int dport)
257{
258 sel->dport = dport;
259
260 return 0;
261}
262
263int xfrmnl_sel_get_dportmask (struct xfrmnl_sel* sel)
264{
265 return sel->dport_mask;
266}
267
268int xfrmnl_sel_set_dportmask (struct xfrmnl_sel* sel, unsigned int dport_mask)
269{
270 sel->dport_mask = dport_mask;
271
272 return 0;
273}
274
275int xfrmnl_sel_get_sport (struct xfrmnl_sel* sel)
276{
277 return sel->sport;
278}
279
280int xfrmnl_sel_set_sport (struct xfrmnl_sel* sel, unsigned int sport)
281{
282 sel->sport = sport;
283
284 return 0;
285}
286
287int xfrmnl_sel_get_sportmask (struct xfrmnl_sel* sel)
288{
289 return sel->sport_mask;
290}
291
292int xfrmnl_sel_set_sportmask (struct xfrmnl_sel* sel, unsigned int sport_mask)
293{
294 sel->sport_mask = sport_mask;
295
296 return 0;
297}
298
299int xfrmnl_sel_get_family(struct xfrmnl_sel *sel)
300{
301 return sel->family;
302}
303
304int xfrmnl_sel_set_family(struct xfrmnl_sel *sel, unsigned int family)
305{
306 sel->family = family;
307
308 return 0;
309}
310
311int xfrmnl_sel_get_prefixlen_d (struct xfrmnl_sel* sel)
312{
313 return sel->prefixlen_d;
314}
315
316int xfrmnl_sel_set_prefixlen_d (struct xfrmnl_sel* sel, unsigned int prefixlen)
317{
318 sel->prefixlen_d = prefixlen;
319
320 return 0;
321}
322
323int xfrmnl_sel_get_prefixlen_s (struct xfrmnl_sel* sel)
324{
325 return sel->prefixlen_s;
326}
327
328int xfrmnl_sel_set_prefixlen_s (struct xfrmnl_sel* sel, unsigned int prefixlen)
329{
330 sel->prefixlen_s = prefixlen;
331
332 return 0;
333}
334
335int xfrmnl_sel_get_proto (struct xfrmnl_sel* sel)
336{
337 return sel->proto;
338}
339
340int xfrmnl_sel_set_proto (struct xfrmnl_sel* sel, unsigned int protocol)
341{
342 sel->proto = protocol;
343
344 return 0;
345}
346
347int xfrmnl_sel_get_ifindex (struct xfrmnl_sel* sel)
348{
349 return sel->ifindex;
350}
351
352int xfrmnl_sel_set_ifindex (struct xfrmnl_sel* sel, unsigned int ifindex)
353{
354 sel->ifindex = ifindex;
355
356 return 0;
357}
358
359int xfrmnl_sel_get_userid (struct xfrmnl_sel* sel)
360{
361 return sel->user;
362}
363
364int xfrmnl_sel_set_userid (struct xfrmnl_sel* sel, unsigned int userid)
365{
366 sel->user = userid;
367 return 0;
368}
369
370
371/** @} */
int xfrmnl_sel_shared(struct xfrmnl_sel *sel)
Check whether an selector object is shared.
Definition selector.c:160
int xfrmnl_sel_cmp(struct xfrmnl_sel *a, struct xfrmnl_sel *b)
Compares two selector objects.
Definition selector.c:180
struct xfrmnl_sel * xfrmnl_sel_alloc()
Allocate new selector object.
Definition selector.c:96
struct xfrmnl_sel * xfrmnl_sel_clone(struct xfrmnl_sel *sel)
Clone existing selector object.
Definition selector.c:115
struct nl_addr * nl_addr_get(struct nl_addr *addr)
Increase the reference counter of an abstract address.
Definition addr.c:525
struct nl_addr * nl_addr_clone(const struct nl_addr *addr)
Clone existing abstract address object.
Definition addr.c:495
int nl_addr_cmp_prefix(const struct nl_addr *a, const struct nl_addr *b)
Compare the prefix of two abstract addresses.
Definition addr.c:626
char * nl_addr2str(const struct nl_addr *addr, char *buf, size_t size)
Convert abstract address object to character string.
Definition addr.c:1001
void nl_addr_put(struct nl_addr *addr)
Decrease the reference counter of an abstract address.
Definition addr.c:541
Dumping parameters.
Definition types.h:32