libnl  3.5.0
neigh.c
1 /* SPDX-License-Identifier: LGPL-2.1-only */
2 /*
3  * lib/route/neigh.c Neighbours
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation version 2.1
8  * of the License.
9  *
10  * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
11  */
12 
13 /**
14  * @ingroup rtnl
15  * @defgroup neigh Neighbours
16  * @brief
17  *
18  * The neighbour table establishes bindings between protocol addresses and
19  * link layer addresses for hosts sharing the same physical link. This
20  * module allows you to access and manipulate the content of these tables.
21  *
22  * @par Neighbour States
23  * @code
24  * NUD_INCOMPLETE
25  * NUD_REACHABLE
26  * NUD_STALE
27  * NUD_DELAY
28  * NUD_PROBE
29  * NUD_FAILED
30  * NUD_NOARP
31  * NUD_PERMANENT
32  * @endcode
33  *
34  * @par Neighbour Flags
35  * @code
36  * NTF_USE
37  * NTF_PROXY
38  * NTF_ROUTER
39  * NTF_SELF
40  * @endcode
41  *
42  * @par Neighbour Identification
43  * A neighbour is uniquely identified by the attributes listed below, whenever
44  * you refer to an existing neighbour all of the attributes must be set.
45  * Neighbours from caches automatically have all required attributes set.
46  * - interface index (rtnl_neigh_set_ifindex())
47  * - destination address (rtnl_neigh_set_dst())
48  *
49  * @par Changeable Attributes
50  * \anchor neigh_changeable
51  * - state (rtnl_neigh_set_state())
52  * - link layer address (rtnl_neigh_set_lladdr())
53  *
54  * @par Required Caches for Dumping
55  * In order to dump neighbour attributes you must provide the following
56  * caches via nl_cache_provide()
57  * - link cache holding all links
58  *
59  * @par TODO
60  * - Document proxy settings
61  * - Document states and their influence
62  *
63  * @par 1) Retrieving information about configured neighbours
64  * @code
65  * // The first step is to retrieve a list of all available neighbour within
66  * // the kernel and put them into a cache.
67  * struct nl_cache *cache = rtnl_neigh_alloc_cache(sk);
68  *
69  * // Neighbours can then be looked up by the interface and destination
70  * // address:
71  * struct rtnl_neigh *neigh = rtnl_neigh_get(cache, ifindex, dst_addr);
72  *
73  * // After successful usage, the object must be given back to the cache
74  * rtnl_neigh_put(neigh);
75  * @endcode
76  *
77  * @par 2) Adding new neighbours
78  * @code
79  * // Allocate an empty neighbour handle to be filled out with the attributes
80  * // of the new neighbour.
81  * struct rtnl_neigh *neigh = rtnl_neigh_alloc();
82  *
83  * // Fill out the attributes of the new neighbour
84  * rtnl_neigh_set_ifindex(neigh, ifindex);
85  * rtnl_neigh_set_dst(neigh, dst_addr);
86  * rtnl_neigh_set_state(neigh, rtnl_neigh_str2state("permanent"));
87  *
88  * // Build the netlink message and send it to the kernel, the operation will
89  * // block until the operation has been completed. Alternatively the required
90  * // netlink message can be built using rtnl_neigh_build_add_request()
91  * // to be sent out using nl_send_auto_complete().
92  * rtnl_neigh_add(sk, neigh, NLM_F_CREATE);
93  *
94  * // Free the memory
95  * rtnl_neigh_put(neigh);
96  * @endcode
97  *
98  * @par 3) Deleting an existing neighbour
99  * @code
100  * // Allocate an empty neighbour object to be filled out with the attributes
101  * // matching the neighbour to be deleted. Alternatively a fully equipped
102  * // neighbour object out of a cache can be used instead.
103  * struct rtnl_neigh *neigh = rtnl_neigh_alloc();
104  *
105  * // Neighbours are uniquely identified by their interface index and
106  * // destination address, you may fill out other attributes but they
107  * // will have no influence.
108  * rtnl_neigh_set_ifindex(neigh, ifindex);
109  * rtnl_neigh_set_dst(neigh, dst_addr);
110  *
111  * // Build the netlink message and send it to the kernel, the operation will
112  * // block until the operation has been completed. Alternatively the required
113  * // netlink message can be built using rtnl_neigh_build_delete_request()
114  * // to be sent out using nl_send_auto_complete().
115  * rtnl_neigh_delete(sk, neigh, 0);
116  *
117  * // Free the memory
118  * rtnl_neigh_put(neigh);
119  * @endcode
120  *
121  * @par 4) Changing neighbour attributes
122  * @code
123  * // Allocate an empty neighbour object to be filled out with the attributes
124  * // matching the neighbour to be changed and the new parameters. Alternatively
125  * // a fully equipped modified neighbour object out of a cache can be used.
126  * struct rtnl_neigh *neigh = rtnl_neigh_alloc();
127  *
128  * // Identify the neighbour to be changed by its interface index and
129  * // destination address
130  * rtnl_neigh_set_ifindex(neigh, ifindex);
131  * rtnl_neigh_set_dst(neigh, dst_addr);
132  *
133  * // The link layer address may be modified, if so it is wise to change
134  * // its state to "permanent" in order to avoid having it overwritten.
135  * rtnl_neigh_set_lladdr(neigh, lladdr);
136  *
137  * // Secondly the state can be modified allowing normal neighbours to be
138  * // converted into permanent entries or to manually confirm a neighbour.
139  * rtnl_neigh_set_state(neigh, state);
140  *
141  * // Build the netlink message and send it to the kernel, the operation will
142  * // block until the operation has been completed. Alternatively the required
143  * // netlink message can be built using rtnl_neigh_build_change_request()
144  * // to be sent out using nl_send_auto_complete().
145  * rtnl_neigh_add(sk, neigh, NLM_F_REPLACE);
146  *
147  * // Free the memory
148  * rtnl_neigh_put(neigh);
149  * @endcode
150  * @{
151  */
152 
153 #include <netlink-private/netlink.h>
154 #include <netlink/netlink.h>
155 #include <netlink/utils.h>
156 #include <netlink/hashtable.h>
157 #include <netlink/route/rtnl.h>
158 #include <netlink/route/neighbour.h>
159 #include <netlink/route/link.h>
160 #include <netlink/hashtable.h>
161 
162 /** @cond SKIP */
163 #define NEIGH_ATTR_FLAGS 0x01
164 #define NEIGH_ATTR_STATE 0x02
165 #define NEIGH_ATTR_LLADDR 0x04
166 #define NEIGH_ATTR_DST 0x08
167 #define NEIGH_ATTR_CACHEINFO 0x10
168 #define NEIGH_ATTR_IFINDEX 0x20
169 #define NEIGH_ATTR_FAMILY 0x40
170 #define NEIGH_ATTR_TYPE 0x80
171 #define NEIGH_ATTR_PROBES 0x100
172 #define NEIGH_ATTR_MASTER 0x200
173 #define NEIGH_ATTR_VLAN 0x400
174 
175 static struct nl_cache_ops rtnl_neigh_ops;
176 static struct nl_object_ops neigh_obj_ops;
177 /** @endcond */
178 
179 static void neigh_free_data(struct nl_object *c)
180 {
181  struct rtnl_neigh *neigh = nl_object_priv(c);
182 
183  if (!neigh)
184  return;
185 
186  nl_addr_put(neigh->n_lladdr);
187  nl_addr_put(neigh->n_dst);
188 }
189 
190 static int neigh_clone(struct nl_object *_dst, struct nl_object *_src)
191 {
192  struct rtnl_neigh *dst = nl_object_priv(_dst);
193  struct rtnl_neigh *src = nl_object_priv(_src);
194 
195  if (src->n_lladdr)
196  if (!(dst->n_lladdr = nl_addr_clone(src->n_lladdr)))
197  return -NLE_NOMEM;
198 
199  if (src->n_dst)
200  if (!(dst->n_dst = nl_addr_clone(src->n_dst)))
201  return -NLE_NOMEM;
202 
203  return 0;
204 }
205 
206 static void neigh_keygen(struct nl_object *obj, uint32_t *hashkey,
207  uint32_t table_sz)
208 {
209  struct rtnl_neigh *neigh = (struct rtnl_neigh *) obj;
210  unsigned int nkey_sz;
211  struct nl_addr *addr = NULL;
212  struct neigh_hash_key {
213  uint32_t n_family;
214  uint32_t n_ifindex;
215  uint16_t n_vlan;
216  char n_addr[0];
217  } __attribute__((packed)) *nkey;
218 #ifdef NL_DEBUG
219  char buf[INET6_ADDRSTRLEN+5];
220 #endif
221 
222  if (neigh->n_family == AF_BRIDGE) {
223  if (neigh->n_lladdr)
224  addr = neigh->n_lladdr;
225  } else if (neigh->n_dst) {
226  addr = neigh->n_dst;
227  }
228 
229  nkey_sz = sizeof(*nkey);
230  if (addr)
231  nkey_sz += nl_addr_get_len(addr);
232 
233  nkey = calloc(1, nkey_sz);
234  if (!nkey) {
235  *hashkey = 0;
236  return;
237  }
238  nkey->n_family = neigh->n_family;
239  if (neigh->n_family == AF_BRIDGE) {
240  nkey->n_vlan = neigh->n_vlan;
241  if (neigh->n_flags & NTF_SELF)
242  nkey->n_ifindex = neigh->n_ifindex;
243  else
244  nkey->n_ifindex = neigh->n_master;
245  } else
246  nkey->n_ifindex = neigh->n_ifindex;
247 
248  if (addr)
249  memcpy(nkey->n_addr,
251  nl_addr_get_len(addr));
252 
253  *hashkey = nl_hash(nkey, nkey_sz, 0) % table_sz;
254 
255  NL_DBG(5, "neigh %p key (fam %d dev %d addr %s) keysz %d hash 0x%x\n",
256  neigh, nkey->n_family, nkey->n_ifindex,
257  nl_addr2str(addr, buf, sizeof(buf)),
258  nkey_sz, *hashkey);
259 
260  free(nkey);
261 
262  return;
263 }
264 
265 static uint64_t neigh_compare(struct nl_object *_a, struct nl_object *_b,
266  uint64_t attrs, int flags)
267 {
268  struct rtnl_neigh *a = (struct rtnl_neigh *) _a;
269  struct rtnl_neigh *b = (struct rtnl_neigh *) _b;
270  uint64_t diff = 0;
271 
272 #define NEIGH_DIFF(ATTR, EXPR) ATTR_DIFF(attrs, NEIGH_ATTR_##ATTR, a, b, EXPR)
273 
274  diff |= NEIGH_DIFF(IFINDEX, a->n_ifindex != b->n_ifindex);
275  diff |= NEIGH_DIFF(FAMILY, a->n_family != b->n_family);
276  diff |= NEIGH_DIFF(TYPE, a->n_type != b->n_type);
277  diff |= NEIGH_DIFF(LLADDR, nl_addr_cmp(a->n_lladdr, b->n_lladdr));
278  diff |= NEIGH_DIFF(DST, nl_addr_cmp(a->n_dst, b->n_dst));
279  diff |= NEIGH_DIFF(MASTER, a->n_master != b->n_master);
280  diff |= NEIGH_DIFF(VLAN, a->n_vlan != b->n_vlan);
281 
282  if (flags & LOOSE_COMPARISON) {
283  diff |= NEIGH_DIFF(STATE,
284  (a->n_state ^ b->n_state) & b->n_state_mask);
285  diff |= NEIGH_DIFF(FLAGS,
286  (a->n_flags ^ b->n_flags) & b->n_flag_mask);
287  } else {
288  diff |= NEIGH_DIFF(STATE, a->n_state != b->n_state);
289  diff |= NEIGH_DIFF(FLAGS, a->n_flags != b->n_flags);
290  }
291 
292 #undef NEIGH_DIFF
293 
294  return diff;
295 }
296 
297 static const struct trans_tbl neigh_attrs[] = {
298  __ADD(NEIGH_ATTR_FLAGS, flags),
299  __ADD(NEIGH_ATTR_STATE, state),
300  __ADD(NEIGH_ATTR_LLADDR, lladdr),
301  __ADD(NEIGH_ATTR_DST, dst),
302  __ADD(NEIGH_ATTR_CACHEINFO, cacheinfo),
303  __ADD(NEIGH_ATTR_IFINDEX, ifindex),
304  __ADD(NEIGH_ATTR_FAMILY, family),
305  __ADD(NEIGH_ATTR_TYPE, type),
306  __ADD(NEIGH_ATTR_PROBES, probes),
307  __ADD(NEIGH_ATTR_MASTER, master),
308  __ADD(NEIGH_ATTR_VLAN, vlan),
309 };
310 
311 static char *neigh_attrs2str(int attrs, char *buf, size_t len)
312 {
313  return __flags2str(attrs, buf, len, neigh_attrs,
314  ARRAY_SIZE(neigh_attrs));
315 }
316 
317 static uint32_t neigh_id_attrs_get(struct nl_object *obj)
318 {
319  struct rtnl_neigh *neigh = (struct rtnl_neigh *)obj;
320 
321  if (neigh->n_family == AF_BRIDGE) {
322  if (neigh->n_flags & NTF_SELF)
323  return (NEIGH_ATTR_LLADDR | NEIGH_ATTR_FAMILY | NEIGH_ATTR_IFINDEX |
324  ((neigh->ce_mask & NEIGH_ATTR_DST) ? NEIGH_ATTR_DST: 0) |
325  ((neigh->ce_mask & NEIGH_ATTR_VLAN) ? NEIGH_ATTR_VLAN : 0));
326  else
327  return (NEIGH_ATTR_LLADDR | NEIGH_ATTR_FAMILY | NEIGH_ATTR_MASTER | NEIGH_ATTR_VLAN);
328  } else
329  return neigh_obj_ops.oo_id_attrs;
330 }
331 
332 static struct nla_policy neigh_policy[NDA_MAX+1] = {
333  [NDA_CACHEINFO] = { .minlen = sizeof(struct nda_cacheinfo) },
334  [NDA_PROBES] = { .type = NLA_U32 },
335 };
336 
337 static int neigh_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who,
338  struct nlmsghdr *n, struct nl_parser_param *pp)
339 {
340  struct rtnl_neigh *neigh;
341  int err;
342 
343  if ((err = rtnl_neigh_parse(n, &neigh)) < 0)
344  return err;
345 
346  err = pp->pp_cb((struct nl_object *) neigh, pp);
347 
348  rtnl_neigh_put(neigh);
349  return err;
350 }
351 
352 
353 int rtnl_neigh_parse(struct nlmsghdr *n, struct rtnl_neigh **result)
354 {
355  struct rtnl_neigh *neigh;
356  struct nlattr *tb[NDA_MAX + 1];
357  struct ndmsg *nm;
358  int err;
359 
360  neigh = rtnl_neigh_alloc();
361  if (!neigh) {
362  err = -NLE_NOMEM;
363  goto errout;
364  }
365 
366  neigh->ce_msgtype = n->nlmsg_type;
367  nm = nlmsg_data(n);
368 
369  err = nlmsg_parse(n, sizeof(*nm), tb, NDA_MAX, neigh_policy);
370  if (err < 0)
371  goto errout;
372 
373  neigh->n_family = nm->ndm_family;
374  neigh->n_ifindex = nm->ndm_ifindex;
375  neigh->n_state = nm->ndm_state;
376  neigh->n_flags = nm->ndm_flags;
377  neigh->n_type = nm->ndm_type;
378 
379  neigh->ce_mask |= (NEIGH_ATTR_FAMILY | NEIGH_ATTR_IFINDEX |
380  NEIGH_ATTR_STATE | NEIGH_ATTR_FLAGS |
381  NEIGH_ATTR_TYPE);
382 
383  if (tb[NDA_LLADDR]) {
384  neigh->n_lladdr = nl_addr_alloc_attr(tb[NDA_LLADDR], AF_UNSPEC);
385  if (!neigh->n_lladdr) {
386  err = -NLE_NOMEM;
387  goto errout;
388  }
389  nl_addr_set_family(neigh->n_lladdr,
390  nl_addr_guess_family(neigh->n_lladdr));
391  neigh->ce_mask |= NEIGH_ATTR_LLADDR;
392  }
393 
394  if (tb[NDA_DST]) {
395  neigh->n_dst = nl_addr_alloc_attr(tb[NDA_DST], AF_UNSPEC);
396  if (!neigh->n_dst) {
397  err = -NLE_NOMEM;
398  goto errout;
399  }
400  nl_addr_set_family(neigh->n_dst,
401  nl_addr_guess_family(neigh->n_dst));
402  neigh->ce_mask |= NEIGH_ATTR_DST;
403  }
404 
405  if (tb[NDA_CACHEINFO]) {
406  struct nda_cacheinfo *ci = nla_data(tb[NDA_CACHEINFO]);
407 
408  neigh->n_cacheinfo.nci_confirmed = ci->ndm_confirmed;
409  neigh->n_cacheinfo.nci_used = ci->ndm_used;
410  neigh->n_cacheinfo.nci_updated = ci->ndm_updated;
411  neigh->n_cacheinfo.nci_refcnt = ci->ndm_refcnt;
412 
413  neigh->ce_mask |= NEIGH_ATTR_CACHEINFO;
414  }
415 
416  if (tb[NDA_PROBES]) {
417  neigh->n_probes = nla_get_u32(tb[NDA_PROBES]);
418  neigh->ce_mask |= NEIGH_ATTR_PROBES;
419  }
420 
421  if (tb[NDA_VLAN]) {
422  neigh->n_vlan = nla_get_u16(tb[NDA_VLAN]);
423  neigh->ce_mask |= NEIGH_ATTR_VLAN;
424  }
425 
426  /*
427  * Get the bridge index for AF_BRIDGE family entries
428  */
429  if (neigh->n_family == AF_BRIDGE) {
430  if (tb[NDA_MASTER]) {
431  neigh->n_master = nla_get_u32(tb[NDA_MASTER]);
432  neigh->ce_mask |= NEIGH_ATTR_MASTER;
433  } else {
434  struct nl_cache *lcache = nl_cache_mngt_require_safe("route/link");
435  if (lcache ) {
436  struct rtnl_link *link = rtnl_link_get(lcache,
437  neigh->n_ifindex);
438  if (link) {
439  neigh->n_master = link->l_master;
440  rtnl_link_put(link);
441  neigh->ce_mask |= NEIGH_ATTR_MASTER;
442  }
443  nl_cache_put(lcache);
444  }
445  }
446  }
447 
448  *result = neigh;
449  return 0;
450 
451 errout:
452  rtnl_neigh_put(neigh);
453  return err;
454 }
455 
456 static int neigh_request_update(struct nl_cache *c, struct nl_sock *h)
457 {
458  int family = c->c_iarg1;
459 
460  if (family == AF_UNSPEC) {
461  return nl_rtgen_request(h, RTM_GETNEIGH, family, NLM_F_DUMP);
462  } else if (family == AF_BRIDGE) {
463  struct ifinfomsg hdr = {.ifi_family = family};
464  struct nl_msg *msg;
465  int err;
466 
467  msg = nlmsg_alloc_simple(RTM_GETNEIGH, NLM_F_REQUEST | NLM_F_DUMP);
468  if (!msg)
469  return -NLE_NOMEM;
470 
471  err = -NLE_MSGSIZE;
472  if (nlmsg_append(msg, &hdr, sizeof(hdr), NLMSG_ALIGNTO) < 0)
473  goto nla_put_failure;
474 
475  err = nl_send_auto(h, msg);
476  if (err > 0)
477  err = 0;
478 
479  nla_put_failure:
480  nlmsg_free(msg);
481  return err;
482  }
483 
484  return -NLE_INVAL;
485 }
486 
487 
488 static void neigh_dump_line(struct nl_object *a, struct nl_dump_params *p)
489 {
490  char dst[INET6_ADDRSTRLEN+5], lladdr[INET6_ADDRSTRLEN+5];
491  struct rtnl_neigh *n = (struct rtnl_neigh *) a;
492  struct nl_cache *link_cache;
493  char state[128], flags[64];
494  char buf[128];
495 
496  link_cache = nl_cache_mngt_require_safe("route/link");
497 
498  if (n->n_family != AF_UNSPEC)
499  nl_dump_line(p, "%s ", nl_af2str(n->n_family, buf, sizeof(buf)));
500 
501  if (n->ce_mask & NEIGH_ATTR_DST)
502  nl_dump_line(p, "%s ", nl_addr2str(n->n_dst, dst, sizeof(dst)));
503 
504  if (link_cache)
505  nl_dump(p, "dev %s ",
506  rtnl_link_i2name(link_cache, n->n_ifindex,
507  state, sizeof(state)));
508  else
509  nl_dump(p, "dev %d ", n->n_ifindex);
510 
511  if (n->ce_mask & NEIGH_ATTR_LLADDR)
512  nl_dump(p, "lladdr %s ",
513  nl_addr2str(n->n_lladdr, lladdr, sizeof(lladdr)));
514 
515  if (n->ce_mask & NEIGH_ATTR_VLAN)
516  nl_dump(p, "vlan %d ", n->n_vlan);
517 
518  if (n->ce_mask & NEIGH_ATTR_MASTER) {
519  if (link_cache)
520  nl_dump(p, "%s ", rtnl_link_i2name(link_cache, n->n_master,
521  state, sizeof(state)));
522  else
523  nl_dump(p, "%d ", n->n_master);
524  }
525 
526  rtnl_neigh_state2str(n->n_state, state, sizeof(state));
527  rtnl_neigh_flags2str(n->n_flags, flags, sizeof(flags));
528 
529  if (state[0])
530  nl_dump(p, "<%s", state);
531  if (flags[0])
532  nl_dump(p, "%s%s", state[0] ? "," : "<", flags);
533  if (state[0] || flags[0])
534  nl_dump(p, ">");
535  nl_dump(p, "\n");
536 
537  if (link_cache)
538  nl_cache_put(link_cache);
539 }
540 
541 static void neigh_dump_details(struct nl_object *a, struct nl_dump_params *p)
542 {
543  char rtn_type[32];
544  struct rtnl_neigh *n = (struct rtnl_neigh *) a;
545  int hz = nl_get_user_hz();
546 
547  neigh_dump_line(a, p);
548 
549  nl_dump_line(p, " refcnt %u type %s confirmed %u used "
550  "%u updated %u\n",
551  n->n_cacheinfo.nci_refcnt,
552  nl_rtntype2str(n->n_type, rtn_type, sizeof(rtn_type)),
553  n->n_cacheinfo.nci_confirmed/hz,
554  n->n_cacheinfo.nci_used/hz, n->n_cacheinfo.nci_updated/hz);
555 }
556 
557 static void neigh_dump_stats(struct nl_object *a, struct nl_dump_params *p)
558 {
559  neigh_dump_details(a, p);
560 }
561 
562 /**
563  * @name Neighbour Object Allocation/Freeage
564  * @{
565  */
566 
567 struct rtnl_neigh *rtnl_neigh_alloc(void)
568 {
569  return (struct rtnl_neigh *) nl_object_alloc(&neigh_obj_ops);
570 }
571 
572 void rtnl_neigh_put(struct rtnl_neigh *neigh)
573 {
574  nl_object_put((struct nl_object *) neigh);
575 }
576 
577 /** @} */
578 
579 /**
580  * @name Neighbour Cache Managament
581  * @{
582  */
583 
584 /**
585  * Build a neighbour cache including all neighbours currently configured in the kernel.
586  * @arg sock Netlink socket.
587  * @arg result Pointer to store resulting cache.
588  *
589  * Allocates a new neighbour cache, initializes it properly and updates it
590  * to include all neighbours currently configured in the kernel.
591  *
592  * @return 0 on success or a negative error code.
593  */
594 int rtnl_neigh_alloc_cache(struct nl_sock *sock, struct nl_cache **result)
595 {
596  return nl_cache_alloc_and_fill(&rtnl_neigh_ops, sock, result);
597 }
598 
599 /**
600  * Build a neighbour cache including all neighbours currently configured in the kernel.
601  * @arg sock Netlink socket.
602  * @arg result Pointer to store resulting cache.
603  * @arg flags Flags to apply to cache before filling
604  *
605  * Allocates a new neighbour cache, initializes it properly and updates it
606  * to include all neighbours currently configured in the kernel.
607  *
608  * @return 0 on success or a negative error code.
609  */
610 int rtnl_neigh_alloc_cache_flags(struct nl_sock *sock, struct nl_cache **result,
611  unsigned int flags)
612 {
613  struct nl_cache * cache;
614  int err;
615 
616  cache = nl_cache_alloc(&rtnl_neigh_ops);
617  if (!cache)
618  return -NLE_NOMEM;
619 
620  nl_cache_set_flags(cache, flags);
621 
622  if (sock && (err = nl_cache_refill(sock, cache)) < 0) {
623  nl_cache_free(cache);
624  return err;
625  }
626 
627  *result = cache;
628  return 0;
629 }
630 
631 /**
632  * Look up a neighbour by interface index and destination address
633  * @arg cache neighbour cache
634  * @arg ifindex interface index the neighbour is on
635  * @arg dst destination address of the neighbour
636  *
637  * @return neighbour handle or NULL if no match was found.
638  */
639 struct rtnl_neigh * rtnl_neigh_get(struct nl_cache *cache, int ifindex,
640  struct nl_addr *dst)
641 {
642  struct rtnl_neigh *neigh;
643 
644  nl_list_for_each_entry(neigh, &cache->c_items, ce_list) {
645  if (neigh->n_ifindex == ifindex &&
646  neigh->n_family == dst->a_family &&
647  !nl_addr_cmp(neigh->n_dst, dst)) {
648  nl_object_get((struct nl_object *) neigh);
649  return neigh;
650  }
651  }
652 
653  return NULL;
654 }
655 
656 /**
657  * Look up a neighbour by interface index, link layer address and vlan id
658  * @arg cache neighbour cache
659  * @arg ifindex interface index the neighbour is on
660  * @arg lladdr link layer address of the neighbour
661  * @arg vlan vlan id of the neighbour
662  *
663  * @return neighbour handle or NULL if no match was found.
664  */
665 struct rtnl_neigh * rtnl_neigh_get_by_vlan(struct nl_cache *cache, int ifindex,
666  struct nl_addr *lladdr, int vlan)
667 {
668  struct rtnl_neigh *neigh;
669 
670  nl_list_for_each_entry(neigh, &cache->c_items, ce_list) {
671  if (neigh->n_ifindex == ifindex &&
672  neigh->n_vlan == vlan &&
673  neigh->n_lladdr && !nl_addr_cmp(neigh->n_lladdr, lladdr)) {
674  nl_object_get((struct nl_object *) neigh);
675  return neigh;
676  }
677  }
678 
679  return NULL;
680 }
681 
682 /** @} */
683 
684 /**
685  * @name Neighbour Addition
686  * @{
687  */
688 
689 static int build_neigh_msg(struct rtnl_neigh *tmpl, int cmd, int flags,
690  struct nl_msg **result)
691 {
692  struct nl_msg *msg;
693  struct ndmsg nhdr = {
694  .ndm_ifindex = tmpl->n_ifindex,
695  .ndm_state = NUD_PERMANENT,
696  };
697 
698  if (tmpl->n_family != AF_BRIDGE) {
699  if (!(tmpl->ce_mask & NEIGH_ATTR_DST))
700  return -NLE_MISSING_ATTR;
701  nhdr.ndm_family = nl_addr_get_family(tmpl->n_dst);
702  }
703  else
704  nhdr.ndm_family = AF_BRIDGE;
705 
706  if (tmpl->ce_mask & NEIGH_ATTR_FLAGS)
707  nhdr.ndm_flags = tmpl->n_flags;
708 
709  if (tmpl->ce_mask & NEIGH_ATTR_STATE)
710  nhdr.ndm_state = tmpl->n_state;
711 
712  msg = nlmsg_alloc_simple(cmd, flags);
713  if (!msg)
714  return -NLE_NOMEM;
715 
716  if (nlmsg_append(msg, &nhdr, sizeof(nhdr), NLMSG_ALIGNTO) < 0)
717  goto nla_put_failure;
718 
719  if (tmpl->n_family != AF_BRIDGE)
720  NLA_PUT_ADDR(msg, NDA_DST, tmpl->n_dst);
721 
722  if (tmpl->ce_mask & NEIGH_ATTR_LLADDR)
723  NLA_PUT_ADDR(msg, NDA_LLADDR, tmpl->n_lladdr);
724 
725  if (tmpl->ce_mask & NEIGH_ATTR_VLAN)
726  NLA_PUT_U16(msg, NDA_VLAN, tmpl->n_vlan);
727 
728  *result = msg;
729  return 0;
730 
731 nla_put_failure:
732  nlmsg_free(msg);
733  return -NLE_MSGSIZE;
734 }
735 
736 /**
737  * Build netlink request message to add a new neighbour
738  * @arg tmpl template with data of new neighbour
739  * @arg flags additional netlink message flags
740  * @arg result Pointer to store resulting message.
741  *
742  * Builds a new netlink message requesting a addition of a new
743  * neighbour. The netlink message header isn't fully equipped with
744  * all relevant fields and must thus be sent out via nl_send_auto_complete()
745  * or supplemented as needed. \a tmpl must contain the attributes of the new
746  * neighbour set via \c rtnl_neigh_set_* functions.
747  *
748  * The following attributes must be set in the template:
749  * - Interface index (rtnl_neigh_set_ifindex())
750  * - State (rtnl_neigh_set_state())
751  * - Destination address (rtnl_neigh_set_dst())
752  * - Link layer address (rtnl_neigh_set_lladdr())
753  *
754  * @return 0 on success or a negative error code.
755  */
756 int rtnl_neigh_build_add_request(struct rtnl_neigh *tmpl, int flags,
757  struct nl_msg **result)
758 {
759  return build_neigh_msg(tmpl, RTM_NEWNEIGH, flags, result);
760 }
761 
762 /**
763  * Add a new neighbour
764  * @arg sk Netlink socket.
765  * @arg tmpl template with requested changes
766  * @arg flags additional netlink message flags
767  *
768  * Builds a netlink message by calling rtnl_neigh_build_add_request(),
769  * sends the request to the kernel and waits for the next ACK to be
770  * received and thus blocks until the request has been fullfilled.
771  *
772  * The following attributes must be set in the template:
773  * - Interface index (rtnl_neigh_set_ifindex())
774  * - State (rtnl_neigh_set_state())
775  * - Destination address (rtnl_neigh_set_dst())
776  * - Link layer address (rtnl_neigh_set_lladdr())
777  *
778  * @return 0 on sucess or a negative error if an error occured.
779  */
780 int rtnl_neigh_add(struct nl_sock *sk, struct rtnl_neigh *tmpl, int flags)
781 {
782  int err;
783  struct nl_msg *msg;
784 
785  if ((err = rtnl_neigh_build_add_request(tmpl, flags, &msg)) < 0)
786  return err;
787 
788  err = nl_send_auto_complete(sk, msg);
789  nlmsg_free(msg);
790  if (err < 0)
791  return err;
792 
793  return wait_for_ack(sk);
794 }
795 
796 /** @} */
797 
798 /**
799  * @name Neighbour Deletion
800  * @{
801  */
802 
803 /**
804  * Build a netlink request message to delete a neighbour
805  * @arg neigh neighbour to delete
806  * @arg flags additional netlink message flags
807  * @arg result Pointer to store resulting message.
808  *
809  * Builds a new netlink message requesting a deletion of a neighbour.
810  * The netlink message header isn't fully equipped with all relevant
811  * fields and must thus be sent out via nl_send_auto_complete()
812  * or supplemented as needed. \a neigh must point to an existing
813  * neighbour.
814  *
815  * @return 0 on success or a negative error code.
816  */
817 int rtnl_neigh_build_delete_request(struct rtnl_neigh *neigh, int flags,
818  struct nl_msg **result)
819 {
820  return build_neigh_msg(neigh, RTM_DELNEIGH, flags, result);
821 }
822 
823 /**
824  * Delete a neighbour
825  * @arg sk Netlink socket.
826  * @arg neigh neighbour to delete
827  * @arg flags additional netlink message flags
828  *
829  * Builds a netlink message by calling rtnl_neigh_build_delete_request(),
830  * sends the request to the kernel and waits for the next ACK to be
831  * received and thus blocks until the request has been fullfilled.
832  *
833  * @return 0 on sucess or a negative error if an error occured.
834  */
835 int rtnl_neigh_delete(struct nl_sock *sk, struct rtnl_neigh *neigh,
836  int flags)
837 {
838  struct nl_msg *msg;
839  int err;
840 
841  if ((err = rtnl_neigh_build_delete_request(neigh, flags, &msg)) < 0)
842  return err;
843 
844  err = nl_send_auto_complete(sk, msg);
845  nlmsg_free(msg);
846  if (err < 0)
847  return err;
848 
849  return wait_for_ack(sk);
850 }
851 
852 /** @} */
853 
854 /**
855  * @name Neighbour States Translations
856  * @{
857  */
858 
859 static const struct trans_tbl neigh_states[] = {
860  __ADD(NUD_INCOMPLETE, incomplete),
861  __ADD(NUD_REACHABLE, reachable),
862  __ADD(NUD_STALE, stale),
863  __ADD(NUD_DELAY, delay),
864  __ADD(NUD_PROBE, probe),
865  __ADD(NUD_FAILED, failed),
866  __ADD(NUD_NOARP, noarp),
867  __ADD(NUD_PERMANENT, permanent),
868 
869  /* Accept this value for backward compatibility. Originally
870  * there was a typo in the string value. This was fixed later,
871  * but we still want to successfully parse "norarp". */
872  __ADD(NUD_NOARP, norarp),
873 };
874 
875 char * rtnl_neigh_state2str(int state, char *buf, size_t len)
876 {
877  return __flags2str(state, buf, len, neigh_states,
878  ARRAY_SIZE(neigh_states) - 1);
879 }
880 
881 int rtnl_neigh_str2state(const char *name)
882 {
883  return __str2type(name, neigh_states, ARRAY_SIZE(neigh_states));
884 }
885 
886 /** @} */
887 
888 /**
889  * @name Neighbour Flags Translations
890  * @{
891  */
892 
893 static const struct trans_tbl neigh_flags[] = {
894  __ADD(NTF_USE, use),
895  __ADD(NTF_PROXY, proxy),
896  __ADD(NTF_ROUTER, router),
897  __ADD(NTF_SELF, self),
898  __ADD(NTF_MASTER, master),
899  __ADD(NTF_EXT_LEARNED, ext_learned),
900  __ADD(NTF_OFFLOADED, offloaded),
901 };
902 
903 char * rtnl_neigh_flags2str(int flags, char *buf, size_t len)
904 {
905  return __flags2str(flags, buf, len, neigh_flags,
906  ARRAY_SIZE(neigh_flags));
907 }
908 
909 int rtnl_neigh_str2flag(const char *name)
910 {
911  return __str2type(name, neigh_flags, ARRAY_SIZE(neigh_flags));
912 }
913 
914 /** @} */
915 
916 /**
917  * @name Attributes
918  * @{
919  */
920 
921 void rtnl_neigh_set_state(struct rtnl_neigh *neigh, int state)
922 {
923  neigh->n_state_mask |= state;
924  neigh->n_state |= state;
925  neigh->ce_mask |= NEIGH_ATTR_STATE;
926 }
927 
928 int rtnl_neigh_get_state(struct rtnl_neigh *neigh)
929 {
930  if (neigh->ce_mask & NEIGH_ATTR_STATE)
931  return neigh->n_state;
932  else
933  return -1;
934 }
935 
936 void rtnl_neigh_unset_state(struct rtnl_neigh *neigh, int state)
937 {
938  neigh->n_state_mask |= state;
939  neigh->n_state &= ~state;
940  neigh->ce_mask |= NEIGH_ATTR_STATE;
941 }
942 
943 void rtnl_neigh_set_flags(struct rtnl_neigh *neigh, unsigned int flags)
944 {
945  neigh->n_flag_mask |= flags;
946  neigh->n_flags |= flags;
947  neigh->ce_mask |= NEIGH_ATTR_FLAGS;
948 }
949 
950 unsigned int rtnl_neigh_get_flags(struct rtnl_neigh *neigh)
951 {
952  return neigh->n_flags;
953 }
954 
955 void rtnl_neigh_unset_flags(struct rtnl_neigh *neigh, unsigned int flags)
956 {
957  neigh->n_flag_mask |= flags;
958  neigh->n_flags &= ~flags;
959  neigh->ce_mask |= NEIGH_ATTR_FLAGS;
960 }
961 
962 void rtnl_neigh_set_ifindex(struct rtnl_neigh *neigh, int ifindex)
963 {
964  neigh->n_ifindex = ifindex;
965  neigh->ce_mask |= NEIGH_ATTR_IFINDEX;
966 }
967 
968 int rtnl_neigh_get_ifindex(struct rtnl_neigh *neigh)
969 {
970  return neigh->n_ifindex;
971 }
972 
973 static inline int __assign_addr(struct rtnl_neigh *neigh, struct nl_addr **pos,
974  struct nl_addr *new, int flag, int nocheck)
975 {
976  if (!nocheck) {
977  if (neigh->ce_mask & NEIGH_ATTR_FAMILY) {
978  if (new->a_family != neigh->n_family)
979  return -NLE_AF_MISMATCH;
980  } else {
981  neigh->n_family = new->a_family;
982  neigh->ce_mask |= NEIGH_ATTR_FAMILY;
983  }
984  }
985 
986  if (*pos)
987  nl_addr_put(*pos);
988 
989  nl_addr_get(new);
990  *pos = new;
991 
992  neigh->ce_mask |= flag;
993 
994  return 0;
995 }
996 
997 void rtnl_neigh_set_lladdr(struct rtnl_neigh *neigh, struct nl_addr *addr)
998 {
999  __assign_addr(neigh, &neigh->n_lladdr, addr, NEIGH_ATTR_LLADDR, 1);
1000 }
1001 
1002 struct nl_addr *rtnl_neigh_get_lladdr(struct rtnl_neigh *neigh)
1003 {
1004  if (neigh->ce_mask & NEIGH_ATTR_LLADDR)
1005  return neigh->n_lladdr;
1006  else
1007  return NULL;
1008 }
1009 
1010 int rtnl_neigh_set_dst(struct rtnl_neigh *neigh, struct nl_addr *addr)
1011 {
1012  return __assign_addr(neigh, &neigh->n_dst, addr,
1013  NEIGH_ATTR_DST, 0);
1014 }
1015 
1016 struct nl_addr *rtnl_neigh_get_dst(struct rtnl_neigh *neigh)
1017 {
1018  if (neigh->ce_mask & NEIGH_ATTR_DST)
1019  return neigh->n_dst;
1020  else
1021  return NULL;
1022 }
1023 
1024 void rtnl_neigh_set_family(struct rtnl_neigh *neigh, int family)
1025 {
1026  neigh->n_family = family;
1027  neigh->ce_mask |= NEIGH_ATTR_FAMILY;
1028 }
1029 
1030 int rtnl_neigh_get_family(struct rtnl_neigh *neigh)
1031 {
1032  return neigh->n_family;
1033 }
1034 
1035 void rtnl_neigh_set_type(struct rtnl_neigh *neigh, int type)
1036 {
1037  neigh->n_type = type;
1038  neigh->ce_mask = NEIGH_ATTR_TYPE;
1039 }
1040 
1041 int rtnl_neigh_get_type(struct rtnl_neigh *neigh)
1042 {
1043  if (neigh->ce_mask & NEIGH_ATTR_TYPE)
1044  return neigh->n_type;
1045  else
1046  return -1;
1047 }
1048 
1049 void rtnl_neigh_set_vlan(struct rtnl_neigh *neigh, int vlan)
1050 {
1051  neigh->n_vlan = vlan;
1052  neigh->ce_mask |= NEIGH_ATTR_VLAN;
1053 }
1054 
1055 int rtnl_neigh_get_vlan(struct rtnl_neigh *neigh)
1056 {
1057  if (neigh->ce_mask & NEIGH_ATTR_VLAN)
1058  return neigh->n_vlan;
1059  else
1060  return -1;
1061 }
1062 
1063 void rtnl_neigh_set_master(struct rtnl_neigh *neigh, int ifindex)
1064 {
1065  neigh->n_master = ifindex;
1066  neigh->ce_mask |= NEIGH_ATTR_MASTER;
1067 }
1068 
1069 int rtnl_neigh_get_master(struct rtnl_neigh *neigh) {
1070  return neigh->n_master;
1071 }
1072 
1073 /** @} */
1074 
1075 static struct nl_object_ops neigh_obj_ops = {
1076  .oo_name = "route/neigh",
1077  .oo_size = sizeof(struct rtnl_neigh),
1078  .oo_free_data = neigh_free_data,
1079  .oo_clone = neigh_clone,
1080  .oo_dump = {
1081  [NL_DUMP_LINE] = neigh_dump_line,
1082  [NL_DUMP_DETAILS] = neigh_dump_details,
1083  [NL_DUMP_STATS] = neigh_dump_stats,
1084  },
1085  .oo_compare = neigh_compare,
1086  .oo_keygen = neigh_keygen,
1087  .oo_attrs2str = neigh_attrs2str,
1088  .oo_id_attrs = (NEIGH_ATTR_IFINDEX | NEIGH_ATTR_DST | NEIGH_ATTR_FAMILY),
1089  .oo_id_attrs_get = neigh_id_attrs_get
1090 };
1091 
1092 static struct nl_af_group neigh_groups[] = {
1093  { AF_UNSPEC, RTNLGRP_NEIGH },
1094  { AF_BRIDGE, RTNLGRP_NEIGH },
1095  { END_OF_GROUP_LIST },
1096 };
1097 
1098 static struct nl_cache_ops rtnl_neigh_ops = {
1099  .co_name = "route/neigh",
1100  .co_hdrsize = sizeof(struct ndmsg),
1101  .co_msgtypes = {
1102  { RTM_NEWNEIGH, NL_ACT_NEW, "new" },
1103  { RTM_DELNEIGH, NL_ACT_DEL, "del" },
1104  { RTM_GETNEIGH, NL_ACT_GET, "get" },
1105  END_OF_MSGTYPES_LIST,
1106  },
1107  .co_protocol = NETLINK_ROUTE,
1108  .co_groups = neigh_groups,
1109  .co_request_update = neigh_request_update,
1110  .co_msg_parser = neigh_msg_parser,
1111  .co_obj_ops = &neigh_obj_ops,
1112 };
1113 
1114 static void __init neigh_init(void)
1115 {
1116  nl_cache_mngt_register(&rtnl_neigh_ops);
1117 }
1118 
1119 static void __exit neigh_exit(void)
1120 {
1121  nl_cache_mngt_unregister(&rtnl_neigh_ops);
1122 }
1123 
1124 /** @} */
int nl_send_auto_complete(struct nl_sock *sk, struct nl_msg *msg)
Definition: nl.c:1248
struct nl_addr * nl_addr_clone(const struct nl_addr *addr)
Clone existing abstract address object.
Definition: addr.c:494
Dump object briefly on one line.
Definition: types.h:22
int nl_get_user_hz(void)
Return the value of HZ.
Definition: utils.c:509
void nlmsg_free(struct nl_msg *msg)
Release a reference from an netlink message.
Definition: msg.c:565
int nlmsg_parse(struct nlmsghdr *nlh, int hdrlen, struct nlattr *tb[], int maxtype, const struct nla_policy *policy)
parse attributes of a netlink message
Definition: msg.c:215
int nl_addr_cmp(const struct nl_addr *a, const struct nl_addr *b)
Compare abstract addresses.
Definition: addr.c:586
int nl_addr_guess_family(const struct nl_addr *addr)
Guess address family of abstract address based on address size.
Definition: addr.c:710
int rtnl_neigh_delete(struct nl_sock *sk, struct rtnl_neigh *neigh, int flags)
Delete a neighbour.
Definition: neigh.c:835
void * nlmsg_data(const struct nlmsghdr *nlh)
Return pointer to message payload.
Definition: msg.c:107
#define NLA_PUT_ADDR(msg, attrtype, addr)
Add address attribute to netlink message.
Definition: attr.h:289
struct nl_object * nl_object_alloc(struct nl_object_ops *ops)
Allocate a new object of kind specified by the operations handle.
Definition: object.c:55
int nl_cache_mngt_unregister(struct nl_cache_ops *ops)
Unregister a set of cache operations.
Definition: cache_mngt.c:288
Attribute validation policy.
Definition: attr.h:69
struct nl_cache * nl_cache_mngt_require_safe(const char *name)
Return cache previously provided via nl_cache_mngt_provide()
Definition: cache_mngt.c:431
void nl_object_get(struct nl_object *obj)
Acquire a reference on a object.
Definition: object.c:205
int rtnl_neigh_alloc_cache_flags(struct nl_sock *sock, struct nl_cache **result, unsigned int flags)
Build a neighbour cache including all neighbours currently configured in the kernel.
Definition: neigh.c:610
struct rtnl_neigh * rtnl_neigh_get_by_vlan(struct nl_cache *cache, int ifindex, struct nl_addr *lladdr, int vlan)
Look up a neighbour by interface index, link layer address and vlan id.
Definition: neigh.c:665
uint32_t nla_get_u32(const struct nlattr *nla)
Return payload of 32 bit integer attribute.
Definition: attr.c:707
struct nl_addr * nl_addr_get(struct nl_addr *addr)
Increase the reference counter of an abstract address.
Definition: addr.c:524
void nl_addr_set_family(struct nl_addr *addr, int family)
Set address family.
Definition: addr.c:881
struct nl_addr * nl_addr_alloc_attr(const struct nlattr *nla, int family)
Allocate abstract address based on Netlink attribute.
Definition: addr.c:263
int rtnl_neigh_add(struct nl_sock *sk, struct rtnl_neigh *tmpl, int flags)
Add a new neighbour.
Definition: neigh.c:780
Dump all attributes but no statistics.
Definition: types.h:23
void nl_cache_free(struct nl_cache *cache)
Free a cache.
Definition: cache.c:409
int nl_cache_mngt_register(struct nl_cache_ops *ops)
Register a set of cache operations.
Definition: cache_mngt.c:253
struct rtnl_neigh * rtnl_neigh_get(struct nl_cache *cache, int ifindex, struct nl_addr *dst)
Look up a neighbour by interface index and destination address.
Definition: neigh.c:639
int rtnl_neigh_build_delete_request(struct rtnl_neigh *neigh, int flags, struct nl_msg **result)
Build a netlink request message to delete a neighbour.
Definition: neigh.c:817
int nl_rtgen_request(struct nl_sock *sk, int type, int family, int flags)
Send routing netlink request message.
Definition: rtnl.c:42
void * nla_data(const struct nlattr *nla)
Return pointer to the payload section.
Definition: attr.c:121
int rtnl_neigh_build_add_request(struct rtnl_neigh *tmpl, int flags, struct nl_msg **result)
Build netlink request message to add a new neighbour.
Definition: neigh.c:756
int rtnl_neigh_alloc_cache(struct nl_sock *sock, struct nl_cache **result)
Build a neighbour cache including all neighbours currently configured in the kernel.
Definition: neigh.c:594
uint16_t minlen
Minimal length of payload required.
Definition: attr.h:74
int nlmsg_append(struct nl_msg *n, void *data, size_t len, int pad)
Append data to tail of a netlink message.
Definition: msg.c:449
int nl_cache_refill(struct nl_sock *sk, struct nl_cache *cache)
(Re)fill a cache with the contents in the kernel.
Definition: cache.c:1041
void nl_object_put(struct nl_object *obj)
Release a reference from an object.
Definition: object.c:216
void nl_addr_put(struct nl_addr *addr)
Decrease the reference counter of an abstract address.
Definition: addr.c:540
struct nl_msg * nlmsg_alloc_simple(int nlmsgtype, int flags)
Allocate a new netlink message.
Definition: msg.c:348
uint16_t nla_get_u16(const struct nlattr *nla)
Return payload of 16 bit integer attribute.
Definition: attr.c:657
32 bit integer
Definition: attr.h:43
Dumping parameters.
Definition: types.h:33
#define NLA_PUT_U16(msg, attrtype, value)
Add 16 bit integer attribute to netlink message.
Definition: attr.h:218
void nl_cache_set_flags(struct nl_cache *cache, unsigned int flags)
Set cache flags.
Definition: cache.c:614
void nl_dump(struct nl_dump_params *params, const char *fmt,...)
Dump a formatted character string.
Definition: utils.c:962
int nl_send_auto(struct nl_sock *sk, struct nl_msg *msg)
Finalize and transmit Netlink message.
Definition: nl.c:517
unsigned int nl_addr_get_len(const struct nl_addr *addr)
Get length of binary address of abstract address object.
Definition: addr.c:954
Dump all attributes including statistics.
Definition: types.h:24
void * nl_addr_get_binary_addr(const struct nl_addr *addr)
Get binary address of abstract address object.
Definition: addr.c:942
int nl_cache_alloc_and_fill(struct nl_cache_ops *ops, struct nl_sock *sock, struct nl_cache **result)
Allocate new cache and fill it.
Definition: cache.c:234
struct nl_cache * nl_cache_alloc(struct nl_cache_ops *ops)
Allocate new cache.
Definition: cache.c:184
char * nl_addr2str(const struct nl_addr *addr, char *buf, size_t size)
Convert abstract address object to character string.
Definition: addr.c:1000
int nl_addr_get_family(const struct nl_addr *addr)
Return address family.
Definition: addr.c:894