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