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 
sel_destroy(struct xfrmnl_sel * sel)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  */
xfrmnl_sel_alloc()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  */
xfrmnl_sel_clone(struct xfrmnl_sel * sel)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 
xfrmnl_sel_get(struct xfrmnl_sel * sel)119 struct xfrmnl_sel* xfrmnl_sel_get(struct xfrmnl_sel* sel)
120 {
121 	sel->refcnt++;
122 
123 	return sel;
124 }
125 
xfrmnl_sel_put(struct xfrmnl_sel * sel)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  */
xfrmnl_sel_shared(struct xfrmnl_sel * sel)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  */
xfrmnl_sel_cmp(struct xfrmnl_sel * a,struct xfrmnl_sel * b)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 
xfrmnl_sel_dump(struct xfrmnl_sel * sel,struct nl_dump_params * p)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  */
xfrmnl_sel_get_daddr(struct xfrmnl_sel * sel)201 struct nl_addr* xfrmnl_sel_get_daddr (struct xfrmnl_sel* sel)
202 {
203 	return sel->daddr;
204 }
205 
xfrmnl_sel_set_daddr(struct xfrmnl_sel * sel,struct nl_addr * addr)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 
xfrmnl_sel_get_saddr(struct xfrmnl_sel * sel)217 struct nl_addr* xfrmnl_sel_get_saddr (struct xfrmnl_sel* sel)
218 {
219 	return sel->saddr;
220 }
221 
xfrmnl_sel_set_saddr(struct xfrmnl_sel * sel,struct nl_addr * addr)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 
xfrmnl_sel_get_dport(struct xfrmnl_sel * sel)233 int xfrmnl_sel_get_dport (struct xfrmnl_sel* sel)
234 {
235 	return sel->dport;
236 }
237 
xfrmnl_sel_set_dport(struct xfrmnl_sel * sel,unsigned int dport)238 int xfrmnl_sel_set_dport (struct xfrmnl_sel* sel, unsigned int dport)
239 {
240 	sel->dport = dport;
241 
242 	return 0;
243 }
244 
xfrmnl_sel_get_dportmask(struct xfrmnl_sel * sel)245 int xfrmnl_sel_get_dportmask (struct xfrmnl_sel* sel)
246 {
247 	return sel->dport_mask;
248 }
249 
xfrmnl_sel_set_dportmask(struct xfrmnl_sel * sel,unsigned int dport_mask)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 
xfrmnl_sel_get_sport(struct xfrmnl_sel * sel)257 int xfrmnl_sel_get_sport (struct xfrmnl_sel* sel)
258 {
259 	return sel->sport;
260 }
261 
xfrmnl_sel_set_sport(struct xfrmnl_sel * sel,unsigned int sport)262 int xfrmnl_sel_set_sport (struct xfrmnl_sel* sel, unsigned int sport)
263 {
264 	sel->sport = sport;
265 
266 	return 0;
267 }
268 
xfrmnl_sel_get_sportmask(struct xfrmnl_sel * sel)269 int xfrmnl_sel_get_sportmask (struct xfrmnl_sel* sel)
270 {
271 	return sel->sport_mask;
272 }
273 
xfrmnl_sel_set_sportmask(struct xfrmnl_sel * sel,unsigned int sport_mask)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 
xfrmnl_sel_get_family(struct xfrmnl_sel * sel)281 int xfrmnl_sel_get_family(struct xfrmnl_sel *sel)
282 {
283 	return sel->family;
284 }
285 
xfrmnl_sel_set_family(struct xfrmnl_sel * sel,unsigned int family)286 int xfrmnl_sel_set_family(struct xfrmnl_sel *sel, unsigned int family)
287 {
288 	sel->family = family;
289 
290 	return 0;
291 }
292 
xfrmnl_sel_get_prefixlen_d(struct xfrmnl_sel * sel)293 int xfrmnl_sel_get_prefixlen_d (struct xfrmnl_sel* sel)
294 {
295 	return sel->prefixlen_d;
296 }
297 
xfrmnl_sel_set_prefixlen_d(struct xfrmnl_sel * sel,unsigned int prefixlen)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 
xfrmnl_sel_get_prefixlen_s(struct xfrmnl_sel * sel)305 int xfrmnl_sel_get_prefixlen_s (struct xfrmnl_sel* sel)
306 {
307 	return sel->prefixlen_s;
308 }
309 
xfrmnl_sel_set_prefixlen_s(struct xfrmnl_sel * sel,unsigned int prefixlen)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 
xfrmnl_sel_get_proto(struct xfrmnl_sel * sel)317 int xfrmnl_sel_get_proto (struct xfrmnl_sel* sel)
318 {
319 	return sel->proto;
320 }
321 
xfrmnl_sel_set_proto(struct xfrmnl_sel * sel,unsigned int protocol)322 int xfrmnl_sel_set_proto (struct xfrmnl_sel* sel, unsigned int protocol)
323 {
324 	sel->proto = protocol;
325 
326 	return 0;
327 }
328 
xfrmnl_sel_get_ifindex(struct xfrmnl_sel * sel)329 int xfrmnl_sel_get_ifindex (struct xfrmnl_sel* sel)
330 {
331 	return sel->ifindex;
332 }
333 
xfrmnl_sel_set_ifindex(struct xfrmnl_sel * sel,unsigned int ifindex)334 int xfrmnl_sel_set_ifindex (struct xfrmnl_sel* sel, unsigned int ifindex)
335 {
336 	sel->ifindex = ifindex;
337 
338 	return 0;
339 }
340 
xfrmnl_sel_get_userid(struct xfrmnl_sel * sel)341 int xfrmnl_sel_get_userid (struct xfrmnl_sel* sel)
342 {
343 	return sel->user;
344 }
345 
xfrmnl_sel_set_userid(struct xfrmnl_sel * sel,unsigned int userid)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 /** @} */
354