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