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