libnl  3.5.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 <netlink/xfrm/selector.h>
51 #include <netlink-private/netlink.h>
52 
53 static void sel_destroy(struct xfrmnl_sel* sel)
54 {
55  if (!sel)
56  return;
57 
58  if (sel->refcnt != 1)
59  {
60  fprintf(stderr, "BUG: %s:%d\n", __FILE__, __LINE__);
61  assert(0);
62  }
63 
64  nl_addr_put (sel->daddr);
65  nl_addr_put (sel->saddr);
66  free(sel);
67 }
68 
69 /**
70  * @name Creating Selector
71  * @{
72  */
73 
74 /**
75  * Allocate new selector object.
76  * @return Newly allocated selector object or NULL
77  */
78 struct xfrmnl_sel* xfrmnl_sel_alloc()
79 {
80  struct xfrmnl_sel* sel;
81 
82  sel = calloc(1, sizeof(struct xfrmnl_sel));
83  if (!sel)
84  return NULL;
85 
86  sel->refcnt = 1;
87 
88  return sel;
89 }
90 
91 /**
92  * Clone existing selector object.
93  * @arg sel Selector object.
94  * @return Newly allocated selector object being a duplicate of the
95  * specified selector object or NULL if a failure occured.
96  */
97 struct xfrmnl_sel* xfrmnl_sel_clone(struct xfrmnl_sel* sel)
98 {
99  struct xfrmnl_sel* new;
100 
101  new = xfrmnl_sel_alloc();
102  if (!new)
103  return NULL;
104 
105  memcpy(new, sel, sizeof(struct xfrmnl_sel));
106  new->daddr = nl_addr_clone(sel->daddr);
107  new->saddr = nl_addr_clone(sel->saddr);
108 
109  return new;
110 }
111 
112 /** @} */
113 
114 /**
115  * @name Managing Usage References
116  * @{
117  */
118 
119 struct xfrmnl_sel* xfrmnl_sel_get(struct xfrmnl_sel* sel)
120 {
121  sel->refcnt++;
122 
123  return sel;
124 }
125 
126 void xfrmnl_sel_put(struct xfrmnl_sel* sel)
127 {
128  if (!sel)
129  return;
130 
131  if (sel->refcnt == 1)
132  sel_destroy(sel);
133  else
134  sel->refcnt--;
135 }
136 
137 /**
138  * Check whether an selector object is shared.
139  * @arg addr Selector object.
140  * @return Non-zero if the selector object is shared, otherwise 0.
141  */
142 int xfrmnl_sel_shared(struct xfrmnl_sel* sel)
143 {
144  return sel->refcnt > 1;
145 }
146 
147 /** @} */
148 
149 /**
150  * @name Miscellaneous
151  * @{
152  */
153 
154 /**
155  * Compares two selector objects.
156  * @arg a A selector object.
157  * @arg b Another selector object.
158  *
159  * @return Non zero if difference is found, 0 otherwise if both
160  * the objects are identical.
161  */
162 int xfrmnl_sel_cmp(struct xfrmnl_sel* a, struct xfrmnl_sel* b)
163 {
164  /* Check for any differences */
165  if ((nl_addr_cmp_prefix (a->daddr, b->daddr) != 0) ||
166  (nl_addr_cmp_prefix (a->saddr, b->saddr) != 0) ||
167  ((a->sport & a->sport_mask) != (b->sport & b->sport_mask)) ||
168  ((a->dport & a->dport_mask) != (b->dport & b->dport_mask)) ||
169  (a->family != b->family) ||
170  (a->proto && (a->proto != b->proto)) ||
171  (a->ifindex && a->ifindex != b->ifindex) ||
172  (a->user != b->user))
173  return 1;
174 
175  /* The objects are identical */
176  return 0;
177 }
178 
179 void xfrmnl_sel_dump(struct xfrmnl_sel* sel, struct nl_dump_params *p)
180 {
181  char dst[INET6_ADDRSTRLEN+5], src[INET6_ADDRSTRLEN+5];
182  char buf [128];
183 
184  nl_dump_line(p, "\t\tsrc %s dst %s family: %s\n", nl_addr2str(sel->saddr, src, sizeof(src)),
185  nl_addr2str (sel->daddr, dst, sizeof (dst)), nl_af2str (sel->family, buf, 128));
186  nl_dump_line (p, "\t\tsrc port/mask: %d/%d dst port/mask: %d/%d\n",
187  sel->dport, sel->dport_mask, sel->sport, sel->sport_mask);
188  nl_dump_line (p, "\t\tprotocol: %s ifindex: %u user: %u\n",
189  nl_ip_proto2str (sel->proto, buf, sizeof(buf)), sel->ifindex, sel->user);
190 
191  return;
192 }
193 
194 
195 /** @} */
196 
197 /**
198  * @name Attributes
199  * @{
200  */
201 struct nl_addr* xfrmnl_sel_get_daddr (struct xfrmnl_sel* sel)
202 {
203  return sel->daddr;
204 }
205 
206 int xfrmnl_sel_set_daddr (struct xfrmnl_sel* sel, struct nl_addr* addr)
207 {
208  /* Increment reference counter on this to keep this address
209  * object around while selector in use */
210  nl_addr_get(addr);
211 
212  sel->daddr = addr;
213 
214  return 0;
215 }
216 
217 struct nl_addr* xfrmnl_sel_get_saddr (struct xfrmnl_sel* sel)
218 {
219  return sel->saddr;
220 }
221 
222 int xfrmnl_sel_set_saddr (struct xfrmnl_sel* sel, struct nl_addr* addr)
223 {
224  /* Increment reference counter on this to keep this address
225  * object around while selector in use */
226  nl_addr_get(addr);
227 
228  sel->saddr = addr;
229 
230  return 0;
231 }
232 
233 int xfrmnl_sel_get_dport (struct xfrmnl_sel* sel)
234 {
235  return sel->dport;
236 }
237 
238 int xfrmnl_sel_set_dport (struct xfrmnl_sel* sel, unsigned int dport)
239 {
240  sel->dport = dport;
241 
242  return 0;
243 }
244 
245 int xfrmnl_sel_get_dportmask (struct xfrmnl_sel* sel)
246 {
247  return sel->dport_mask;
248 }
249 
250 int xfrmnl_sel_set_dportmask (struct xfrmnl_sel* sel, unsigned int dport_mask)
251 {
252  sel->dport_mask = dport_mask;
253 
254  return 0;
255 }
256 
257 int xfrmnl_sel_get_sport (struct xfrmnl_sel* sel)
258 {
259  return sel->sport;
260 }
261 
262 int xfrmnl_sel_set_sport (struct xfrmnl_sel* sel, unsigned int sport)
263 {
264  sel->sport = sport;
265 
266  return 0;
267 }
268 
269 int xfrmnl_sel_get_sportmask (struct xfrmnl_sel* sel)
270 {
271  return sel->sport_mask;
272 }
273 
274 int xfrmnl_sel_set_sportmask (struct xfrmnl_sel* sel, unsigned int sport_mask)
275 {
276  sel->sport_mask = sport_mask;
277 
278  return 0;
279 }
280 
281 int xfrmnl_sel_get_family(struct xfrmnl_sel *sel)
282 {
283  return sel->family;
284 }
285 
286 int xfrmnl_sel_set_family(struct xfrmnl_sel *sel, unsigned int family)
287 {
288  sel->family = family;
289 
290  return 0;
291 }
292 
293 int xfrmnl_sel_get_prefixlen_d (struct xfrmnl_sel* sel)
294 {
295  return sel->prefixlen_d;
296 }
297 
298 int xfrmnl_sel_set_prefixlen_d (struct xfrmnl_sel* sel, unsigned int prefixlen)
299 {
300  sel->prefixlen_d = prefixlen;
301 
302  return 0;
303 }
304 
305 int xfrmnl_sel_get_prefixlen_s (struct xfrmnl_sel* sel)
306 {
307  return sel->prefixlen_s;
308 }
309 
310 int xfrmnl_sel_set_prefixlen_s (struct xfrmnl_sel* sel, unsigned int prefixlen)
311 {
312  sel->prefixlen_s = prefixlen;
313 
314  return 0;
315 }
316 
317 int xfrmnl_sel_get_proto (struct xfrmnl_sel* sel)
318 {
319  return sel->proto;
320 }
321 
322 int xfrmnl_sel_set_proto (struct xfrmnl_sel* sel, unsigned int protocol)
323 {
324  sel->proto = protocol;
325 
326  return 0;
327 }
328 
329 int xfrmnl_sel_get_ifindex (struct xfrmnl_sel* sel)
330 {
331  return sel->ifindex;
332 }
333 
334 int xfrmnl_sel_set_ifindex (struct xfrmnl_sel* sel, unsigned int ifindex)
335 {
336  sel->ifindex = ifindex;
337 
338  return 0;
339 }
340 
341 int xfrmnl_sel_get_userid (struct xfrmnl_sel* sel)
342 {
343  return sel->user;
344 }
345 
346 int xfrmnl_sel_set_userid (struct xfrmnl_sel* sel, unsigned int userid)
347 {
348  sel->user = userid;
349  return 0;
350 }
351 
352 
353 /** @} */
struct nl_addr * nl_addr_clone(const struct nl_addr *addr)
Clone existing abstract address object.
Definition: addr.c:494
struct nl_addr * nl_addr_get(struct nl_addr *addr)
Increase the reference counter of an abstract address.
Definition: addr.c:524
int xfrmnl_sel_shared(struct xfrmnl_sel *sel)
Check whether an selector object is shared.
Definition: selector.c:142
int xfrmnl_sel_cmp(struct xfrmnl_sel *a, struct xfrmnl_sel *b)
Compares two selector objects.
Definition: selector.c:162
void nl_addr_put(struct nl_addr *addr)
Decrease the reference counter of an abstract address.
Definition: addr.c:540
struct xfrmnl_sel * xfrmnl_sel_alloc()
Allocate new selector object.
Definition: selector.c:78
struct xfrmnl_sel * xfrmnl_sel_clone(struct xfrmnl_sel *sel)
Clone existing selector object.
Definition: selector.c:97
Dumping parameters.
Definition: types.h:33
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:625
char * nl_addr2str(const struct nl_addr *addr, char *buf, size_t size)
Convert abstract address object to character string.
Definition: addr.c:1000