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