xref: /aosp_15_r20/external/libnl/lib/xfrm/selector.c (revision 4dc78e53d49367fa8e61b07018507c90983a077d)
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. */
55 struct 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 
sel_destroy(struct xfrmnl_sel * sel)71 static 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  */
xfrmnl_sel_alloc()96 struct xfrmnl_sel* xfrmnl_sel_alloc()
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  */
xfrmnl_sel_clone(struct xfrmnl_sel * sel)115 struct xfrmnl_sel* xfrmnl_sel_clone(struct xfrmnl_sel* sel)
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 
xfrmnl_sel_get(struct xfrmnl_sel * sel)137 struct xfrmnl_sel* xfrmnl_sel_get(struct xfrmnl_sel* sel)
138 {
139 	sel->refcnt++;
140 
141 	return sel;
142 }
143 
xfrmnl_sel_put(struct xfrmnl_sel * sel)144 void 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  */
xfrmnl_sel_shared(struct xfrmnl_sel * sel)160 int xfrmnl_sel_shared(struct xfrmnl_sel* sel)
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  */
xfrmnl_sel_cmp(struct xfrmnl_sel * a,struct xfrmnl_sel * b)180 int 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 
xfrmnl_sel_dump(struct xfrmnl_sel * sel,struct nl_dump_params * p)197 void 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  */
xfrmnl_sel_get_daddr(struct xfrmnl_sel * sel)219 struct nl_addr* xfrmnl_sel_get_daddr (struct xfrmnl_sel* sel)
220 {
221 	return sel->daddr;
222 }
223 
xfrmnl_sel_set_daddr(struct xfrmnl_sel * sel,struct nl_addr * addr)224 int 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 
xfrmnl_sel_get_saddr(struct xfrmnl_sel * sel)235 struct nl_addr* xfrmnl_sel_get_saddr (struct xfrmnl_sel* sel)
236 {
237 	return sel->saddr;
238 }
239 
xfrmnl_sel_set_saddr(struct xfrmnl_sel * sel,struct nl_addr * addr)240 int 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 
xfrmnl_sel_get_dport(struct xfrmnl_sel * sel)251 int xfrmnl_sel_get_dport (struct xfrmnl_sel* sel)
252 {
253 	return sel->dport;
254 }
255 
xfrmnl_sel_set_dport(struct xfrmnl_sel * sel,unsigned int dport)256 int xfrmnl_sel_set_dport (struct xfrmnl_sel* sel, unsigned int dport)
257 {
258 	sel->dport = dport;
259 
260 	return 0;
261 }
262 
xfrmnl_sel_get_dportmask(struct xfrmnl_sel * sel)263 int xfrmnl_sel_get_dportmask (struct xfrmnl_sel* sel)
264 {
265 	return sel->dport_mask;
266 }
267 
xfrmnl_sel_set_dportmask(struct xfrmnl_sel * sel,unsigned int dport_mask)268 int 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 
xfrmnl_sel_get_sport(struct xfrmnl_sel * sel)275 int xfrmnl_sel_get_sport (struct xfrmnl_sel* sel)
276 {
277 	return sel->sport;
278 }
279 
xfrmnl_sel_set_sport(struct xfrmnl_sel * sel,unsigned int sport)280 int xfrmnl_sel_set_sport (struct xfrmnl_sel* sel, unsigned int sport)
281 {
282 	sel->sport = sport;
283 
284 	return 0;
285 }
286 
xfrmnl_sel_get_sportmask(struct xfrmnl_sel * sel)287 int xfrmnl_sel_get_sportmask (struct xfrmnl_sel* sel)
288 {
289 	return sel->sport_mask;
290 }
291 
xfrmnl_sel_set_sportmask(struct xfrmnl_sel * sel,unsigned int sport_mask)292 int 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 
xfrmnl_sel_get_family(struct xfrmnl_sel * sel)299 int xfrmnl_sel_get_family(struct xfrmnl_sel *sel)
300 {
301 	return sel->family;
302 }
303 
xfrmnl_sel_set_family(struct xfrmnl_sel * sel,unsigned int family)304 int xfrmnl_sel_set_family(struct xfrmnl_sel *sel, unsigned int family)
305 {
306 	sel->family = family;
307 
308 	return 0;
309 }
310 
xfrmnl_sel_get_prefixlen_d(struct xfrmnl_sel * sel)311 int xfrmnl_sel_get_prefixlen_d (struct xfrmnl_sel* sel)
312 {
313 	return sel->prefixlen_d;
314 }
315 
xfrmnl_sel_set_prefixlen_d(struct xfrmnl_sel * sel,unsigned int prefixlen)316 int xfrmnl_sel_set_prefixlen_d (struct xfrmnl_sel* sel, unsigned int prefixlen)
317 {
318 	sel->prefixlen_d = prefixlen;
319 
320 	return 0;
321 }
322 
xfrmnl_sel_get_prefixlen_s(struct xfrmnl_sel * sel)323 int xfrmnl_sel_get_prefixlen_s (struct xfrmnl_sel* sel)
324 {
325 	return sel->prefixlen_s;
326 }
327 
xfrmnl_sel_set_prefixlen_s(struct xfrmnl_sel * sel,unsigned int prefixlen)328 int xfrmnl_sel_set_prefixlen_s (struct xfrmnl_sel* sel, unsigned int prefixlen)
329 {
330 	sel->prefixlen_s = prefixlen;
331 
332 	return 0;
333 }
334 
xfrmnl_sel_get_proto(struct xfrmnl_sel * sel)335 int xfrmnl_sel_get_proto (struct xfrmnl_sel* sel)
336 {
337 	return sel->proto;
338 }
339 
xfrmnl_sel_set_proto(struct xfrmnl_sel * sel,unsigned int protocol)340 int xfrmnl_sel_set_proto (struct xfrmnl_sel* sel, unsigned int protocol)
341 {
342 	sel->proto = protocol;
343 
344 	return 0;
345 }
346 
xfrmnl_sel_get_ifindex(struct xfrmnl_sel * sel)347 int xfrmnl_sel_get_ifindex (struct xfrmnl_sel* sel)
348 {
349 	return sel->ifindex;
350 }
351 
xfrmnl_sel_set_ifindex(struct xfrmnl_sel * sel,unsigned int ifindex)352 int xfrmnl_sel_set_ifindex (struct xfrmnl_sel* sel, unsigned int ifindex)
353 {
354 	sel->ifindex = ifindex;
355 
356 	return 0;
357 }
358 
xfrmnl_sel_get_userid(struct xfrmnl_sel * sel)359 int xfrmnl_sel_get_userid (struct xfrmnl_sel* sel)
360 {
361 	return sel->user;
362 }
363 
xfrmnl_sel_set_userid(struct xfrmnl_sel * sel,unsigned int userid)364 int xfrmnl_sel_set_userid (struct xfrmnl_sel* sel, unsigned int userid)
365 {
366 	sel->user   = userid;
367 	return 0;
368 }
369 
370 
371 /** @} */
372