libnl  3.3.0
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  if (tb[NDA_MASTER]) {
426  neigh->n_master = nla_get_u32(tb[NDA_MASTER]);
427  neigh->ce_mask |= NEIGH_ATTR_MASTER;
428  } else {
429  struct nl_cache *lcache = nl_cache_mngt_require_safe("route/link");
430  if (lcache ) {
431  struct rtnl_link *link = rtnl_link_get(lcache,
432  neigh->n_ifindex);
433  if (link) {
434  neigh->n_master = link->l_master;
435  rtnl_link_put(link);
436  neigh->ce_mask |= NEIGH_ATTR_MASTER;
437  }
438  nl_cache_put(lcache);
439  }
440  }
441  }
442 
443  *result = neigh;
444  return 0;
445 
446 errout:
447  rtnl_neigh_put(neigh);
448  return err;
449 }
450 
451 static int neigh_request_update(struct nl_cache *c, struct nl_sock *h)
452 {
453  int family = c->c_iarg1;
454 
455  return nl_rtgen_request(h, RTM_GETNEIGH, family, NLM_F_DUMP);
456 }
457 
458 
459 static void neigh_dump_line(struct nl_object *a, struct nl_dump_params *p)
460 {
461  char dst[INET6_ADDRSTRLEN+5], lladdr[INET6_ADDRSTRLEN+5];
462  struct rtnl_neigh *n = (struct rtnl_neigh *) a;
463  struct nl_cache *link_cache;
464  char state[128], flags[64];
465 
466  link_cache = nl_cache_mngt_require_safe("route/link");
467 
468  if (n->n_family != AF_BRIDGE)
469  nl_dump_line(p, "%s ", nl_addr2str(n->n_dst, dst, sizeof(dst)));
470 
471  if (link_cache)
472  nl_dump(p, "dev %s ",
473  rtnl_link_i2name(link_cache, n->n_ifindex,
474  state, sizeof(state)));
475  else
476  nl_dump(p, "dev %d ", n->n_ifindex);
477 
478  if (n->ce_mask & NEIGH_ATTR_LLADDR)
479  nl_dump(p, "lladdr %s ",
480  nl_addr2str(n->n_lladdr, lladdr, sizeof(lladdr)));
481 
482  if (n->ce_mask & NEIGH_ATTR_VLAN)
483  nl_dump(p, "vlan %d ", n->n_vlan);
484 
485  rtnl_neigh_state2str(n->n_state, state, sizeof(state));
486  rtnl_neigh_flags2str(n->n_flags, flags, sizeof(flags));
487 
488  if (state[0])
489  nl_dump(p, "<%s", state);
490  if (flags[0])
491  nl_dump(p, "%s%s", state[0] ? "," : "<", flags);
492  if (state[0] || flags[0])
493  nl_dump(p, ">");
494  nl_dump(p, "\n");
495 
496  if (link_cache)
497  nl_cache_put(link_cache);
498 }
499 
500 static void neigh_dump_details(struct nl_object *a, struct nl_dump_params *p)
501 {
502  char rtn_type[32];
503  struct rtnl_neigh *n = (struct rtnl_neigh *) a;
504  int hz = nl_get_user_hz();
505 
506  neigh_dump_line(a, p);
507 
508  nl_dump_line(p, " refcnt %u type %s confirmed %u used "
509  "%u updated %u\n",
510  n->n_cacheinfo.nci_refcnt,
511  nl_rtntype2str(n->n_type, rtn_type, sizeof(rtn_type)),
512  n->n_cacheinfo.nci_confirmed/hz,
513  n->n_cacheinfo.nci_used/hz, n->n_cacheinfo.nci_updated/hz);
514 }
515 
516 static void neigh_dump_stats(struct nl_object *a, struct nl_dump_params *p)
517 {
518  neigh_dump_details(a, p);
519 }
520 
521 /**
522  * @name Neighbour Object Allocation/Freeage
523  * @{
524  */
525 
526 struct rtnl_neigh *rtnl_neigh_alloc(void)
527 {
528  return (struct rtnl_neigh *) nl_object_alloc(&neigh_obj_ops);
529 }
530 
531 void rtnl_neigh_put(struct rtnl_neigh *neigh)
532 {
533  nl_object_put((struct nl_object *) neigh);
534 }
535 
536 /** @} */
537 
538 /**
539  * @name Neighbour Cache Managament
540  * @{
541  */
542 
543 /**
544  * Build a neighbour cache including all neighbours currently configured in the kernel.
545  * @arg sock Netlink socket.
546  * @arg result Pointer to store resulting cache.
547  *
548  * Allocates a new neighbour cache, initializes it properly and updates it
549  * to include all neighbours currently configured in the kernel.
550  *
551  * @return 0 on success or a negative error code.
552  */
553 int rtnl_neigh_alloc_cache(struct nl_sock *sock, struct nl_cache **result)
554 {
555  return nl_cache_alloc_and_fill(&rtnl_neigh_ops, sock, result);
556 }
557 
558 /**
559  * Build a neighbour cache including all neighbours currently configured in the kernel.
560  * @arg sock Netlink socket.
561  * @arg result Pointer to store resulting cache.
562  * @arg flags Flags to apply to cache before filling
563  *
564  * Allocates a new neighbour cache, initializes it properly and updates it
565  * to include all neighbours currently configured in the kernel.
566  *
567  * @return 0 on success or a negative error code.
568  */
569 int rtnl_neigh_alloc_cache_flags(struct nl_sock *sock, struct nl_cache **result,
570  unsigned int flags)
571 {
572  struct nl_cache * cache;
573  int err;
574 
575  cache = nl_cache_alloc(&rtnl_neigh_ops);
576  if (!cache)
577  return -NLE_NOMEM;
578 
579  nl_cache_set_flags(cache, flags);
580 
581  if (sock && (err = nl_cache_refill(sock, cache)) < 0) {
582  nl_cache_free(cache);
583  return err;
584  }
585 
586  *result = cache;
587  return 0;
588 }
589 
590 /**
591  * Look up a neighbour by interface index and destination address
592  * @arg cache neighbour cache
593  * @arg ifindex interface index the neighbour is on
594  * @arg dst destination address of the neighbour
595  *
596  * @return neighbour handle or NULL if no match was found.
597  */
598 struct rtnl_neigh * rtnl_neigh_get(struct nl_cache *cache, int ifindex,
599  struct nl_addr *dst)
600 {
601  struct rtnl_neigh *neigh;
602 
603  nl_list_for_each_entry(neigh, &cache->c_items, ce_list) {
604  if (neigh->n_ifindex == ifindex &&
605  !nl_addr_cmp(neigh->n_dst, dst)) {
606  nl_object_get((struct nl_object *) neigh);
607  return neigh;
608  }
609  }
610 
611  return NULL;
612 }
613 
614 /**
615  * Look up a neighbour by interface index, link layer address and vlan id
616  * @arg cache neighbour cache
617  * @arg ifindex interface index the neighbour is on
618  * @arg lladdr link layer address of the neighbour
619  * @arg vlan vlan id of the neighbour
620  *
621  * @return neighbour handle or NULL if no match was found.
622  */
623 struct rtnl_neigh * rtnl_neigh_get_by_vlan(struct nl_cache *cache, int ifindex,
624  struct nl_addr *lladdr, int vlan)
625 {
626  struct rtnl_neigh *neigh;
627 
628  nl_list_for_each_entry(neigh, &cache->c_items, ce_list) {
629  if (neigh->n_ifindex == ifindex &&
630  neigh->n_vlan == vlan &&
631  neigh->n_lladdr && !nl_addr_cmp(neigh->n_lladdr, lladdr)) {
632  nl_object_get((struct nl_object *) neigh);
633  return neigh;
634  }
635  }
636 
637  return NULL;
638 }
639 
640 /** @} */
641 
642 /**
643  * @name Neighbour Addition
644  * @{
645  */
646 
647 static int build_neigh_msg(struct rtnl_neigh *tmpl, int cmd, int flags,
648  struct nl_msg **result)
649 {
650  struct nl_msg *msg;
651  struct ndmsg nhdr = {
652  .ndm_ifindex = tmpl->n_ifindex,
653  .ndm_state = NUD_PERMANENT,
654  };
655 
656  if (tmpl->n_family != AF_BRIDGE) {
657  if (!(tmpl->ce_mask & NEIGH_ATTR_DST))
658  return -NLE_MISSING_ATTR;
659  nhdr.ndm_family = nl_addr_get_family(tmpl->n_dst);
660  }
661  else
662  nhdr.ndm_family = AF_BRIDGE;
663 
664  if (tmpl->ce_mask & NEIGH_ATTR_FLAGS)
665  nhdr.ndm_flags = tmpl->n_flags;
666 
667  if (tmpl->ce_mask & NEIGH_ATTR_STATE)
668  nhdr.ndm_state = tmpl->n_state;
669 
670  msg = nlmsg_alloc_simple(cmd, flags);
671  if (!msg)
672  return -NLE_NOMEM;
673 
674  if (nlmsg_append(msg, &nhdr, sizeof(nhdr), NLMSG_ALIGNTO) < 0)
675  goto nla_put_failure;
676 
677  if (tmpl->n_family != AF_BRIDGE)
678  NLA_PUT_ADDR(msg, NDA_DST, tmpl->n_dst);
679 
680  if (tmpl->ce_mask & NEIGH_ATTR_LLADDR)
681  NLA_PUT_ADDR(msg, NDA_LLADDR, tmpl->n_lladdr);
682 
683  if (tmpl->ce_mask & NEIGH_ATTR_VLAN)
684  NLA_PUT_U16(msg, NDA_VLAN, tmpl->n_vlan);
685 
686  *result = msg;
687  return 0;
688 
689 nla_put_failure:
690  nlmsg_free(msg);
691  return -NLE_MSGSIZE;
692 }
693 
694 /**
695  * Build netlink request message to add a new neighbour
696  * @arg tmpl template with data of new neighbour
697  * @arg flags additional netlink message flags
698  * @arg result Pointer to store resulting message.
699  *
700  * Builds a new netlink message requesting a addition of a new
701  * neighbour. The netlink message header isn't fully equipped with
702  * all relevant fields and must thus be sent out via nl_send_auto_complete()
703  * or supplemented as needed. \a tmpl must contain the attributes of the new
704  * neighbour set via \c rtnl_neigh_set_* functions.
705  *
706  * The following attributes must be set in the template:
707  * - Interface index (rtnl_neigh_set_ifindex())
708  * - State (rtnl_neigh_set_state())
709  * - Destination address (rtnl_neigh_set_dst())
710  * - Link layer address (rtnl_neigh_set_lladdr())
711  *
712  * @return 0 on success or a negative error code.
713  */
714 int rtnl_neigh_build_add_request(struct rtnl_neigh *tmpl, int flags,
715  struct nl_msg **result)
716 {
717  return build_neigh_msg(tmpl, RTM_NEWNEIGH, flags, result);
718 }
719 
720 /**
721  * Add a new neighbour
722  * @arg sk Netlink socket.
723  * @arg tmpl template with requested changes
724  * @arg flags additional netlink message flags
725  *
726  * Builds a netlink message by calling rtnl_neigh_build_add_request(),
727  * sends the request to the kernel and waits for the next ACK to be
728  * received and thus blocks until the request has been fullfilled.
729  *
730  * The following attributes must be set in the template:
731  * - Interface index (rtnl_neigh_set_ifindex())
732  * - State (rtnl_neigh_set_state())
733  * - Destination address (rtnl_neigh_set_dst())
734  * - Link layer address (rtnl_neigh_set_lladdr())
735  *
736  * @return 0 on sucess or a negative error if an error occured.
737  */
738 int rtnl_neigh_add(struct nl_sock *sk, struct rtnl_neigh *tmpl, int flags)
739 {
740  int err;
741  struct nl_msg *msg;
742 
743  if ((err = rtnl_neigh_build_add_request(tmpl, flags, &msg)) < 0)
744  return err;
745 
746  err = nl_send_auto_complete(sk, msg);
747  nlmsg_free(msg);
748  if (err < 0)
749  return err;
750 
751  return wait_for_ack(sk);
752 }
753 
754 /** @} */
755 
756 /**
757  * @name Neighbour Deletion
758  * @{
759  */
760 
761 /**
762  * Build a netlink request message to delete a neighbour
763  * @arg neigh neighbour to delete
764  * @arg flags additional netlink message flags
765  * @arg result Pointer to store resulting message.
766  *
767  * Builds a new netlink message requesting a deletion of a neighbour.
768  * The netlink message header isn't fully equipped with all relevant
769  * fields and must thus be sent out via nl_send_auto_complete()
770  * or supplemented as needed. \a neigh must point to an existing
771  * neighbour.
772  *
773  * @return 0 on success or a negative error code.
774  */
775 int rtnl_neigh_build_delete_request(struct rtnl_neigh *neigh, int flags,
776  struct nl_msg **result)
777 {
778  return build_neigh_msg(neigh, RTM_DELNEIGH, flags, result);
779 }
780 
781 /**
782  * Delete a neighbour
783  * @arg sk Netlink socket.
784  * @arg neigh neighbour to delete
785  * @arg flags additional netlink message flags
786  *
787  * Builds a netlink message by calling rtnl_neigh_build_delete_request(),
788  * sends the request to the kernel and waits for the next ACK to be
789  * received and thus blocks until the request has been fullfilled.
790  *
791  * @return 0 on sucess or a negative error if an error occured.
792  */
793 int rtnl_neigh_delete(struct nl_sock *sk, struct rtnl_neigh *neigh,
794  int flags)
795 {
796  struct nl_msg *msg;
797  int err;
798 
799  if ((err = rtnl_neigh_build_delete_request(neigh, flags, &msg)) < 0)
800  return err;
801 
802  err = nl_send_auto_complete(sk, msg);
803  nlmsg_free(msg);
804  if (err < 0)
805  return err;
806 
807  return wait_for_ack(sk);
808 }
809 
810 /** @} */
811 
812 /**
813  * @name Neighbour States Translations
814  * @{
815  */
816 
817 static const struct trans_tbl neigh_states[] = {
818  __ADD(NUD_INCOMPLETE, incomplete),
819  __ADD(NUD_REACHABLE, reachable),
820  __ADD(NUD_STALE, stale),
821  __ADD(NUD_DELAY, delay),
822  __ADD(NUD_PROBE, probe),
823  __ADD(NUD_FAILED, failed),
824  __ADD(NUD_NOARP, noarp),
825  __ADD(NUD_PERMANENT, permanent),
826 
827  /* Accept this value for backward compatibility. Originally
828  * there was a typo in the string value. This was fixed later,
829  * but we still want to successfully parse "norarp". */
830  __ADD(NUD_NOARP, norarp),
831 };
832 
833 char * rtnl_neigh_state2str(int state, char *buf, size_t len)
834 {
835  return __flags2str(state, buf, len, neigh_states,
836  ARRAY_SIZE(neigh_states) - 1);
837 }
838 
839 int rtnl_neigh_str2state(const char *name)
840 {
841  return __str2type(name, neigh_states, ARRAY_SIZE(neigh_states));
842 }
843 
844 /** @} */
845 
846 /**
847  * @name Neighbour Flags Translations
848  * @{
849  */
850 
851 static const struct trans_tbl neigh_flags[] = {
852  __ADD(NTF_USE, use),
853  __ADD(NTF_PROXY, proxy),
854  __ADD(NTF_ROUTER, router),
855  __ADD(NTF_SELF, self),
856 };
857 
858 char * rtnl_neigh_flags2str(int flags, char *buf, size_t len)
859 {
860  return __flags2str(flags, buf, len, neigh_flags,
861  ARRAY_SIZE(neigh_flags));
862 }
863 
864 int rtnl_neigh_str2flag(const char *name)
865 {
866  return __str2type(name, neigh_flags, ARRAY_SIZE(neigh_flags));
867 }
868 
869 /** @} */
870 
871 /**
872  * @name Attributes
873  * @{
874  */
875 
876 void rtnl_neigh_set_state(struct rtnl_neigh *neigh, int state)
877 {
878  neigh->n_state_mask |= state;
879  neigh->n_state |= state;
880  neigh->ce_mask |= NEIGH_ATTR_STATE;
881 }
882 
883 int rtnl_neigh_get_state(struct rtnl_neigh *neigh)
884 {
885  if (neigh->ce_mask & NEIGH_ATTR_STATE)
886  return neigh->n_state;
887  else
888  return -1;
889 }
890 
891 void rtnl_neigh_unset_state(struct rtnl_neigh *neigh, int state)
892 {
893  neigh->n_state_mask |= state;
894  neigh->n_state &= ~state;
895  neigh->ce_mask |= NEIGH_ATTR_STATE;
896 }
897 
898 void rtnl_neigh_set_flags(struct rtnl_neigh *neigh, unsigned int flags)
899 {
900  neigh->n_flag_mask |= flags;
901  neigh->n_flags |= flags;
902  neigh->ce_mask |= NEIGH_ATTR_FLAGS;
903 }
904 
905 unsigned int rtnl_neigh_get_flags(struct rtnl_neigh *neigh)
906 {
907  return neigh->n_flags;
908 }
909 
910 void rtnl_neigh_unset_flags(struct rtnl_neigh *neigh, unsigned int flags)
911 {
912  neigh->n_flag_mask |= flags;
913  neigh->n_flags &= ~flags;
914  neigh->ce_mask |= NEIGH_ATTR_FLAGS;
915 }
916 
917 void rtnl_neigh_set_ifindex(struct rtnl_neigh *neigh, int ifindex)
918 {
919  neigh->n_ifindex = ifindex;
920  neigh->ce_mask |= NEIGH_ATTR_IFINDEX;
921 }
922 
923 int rtnl_neigh_get_ifindex(struct rtnl_neigh *neigh)
924 {
925  return neigh->n_ifindex;
926 }
927 
928 static inline int __assign_addr(struct rtnl_neigh *neigh, struct nl_addr **pos,
929  struct nl_addr *new, int flag, int nocheck)
930 {
931  if (!nocheck) {
932  if (neigh->ce_mask & NEIGH_ATTR_FAMILY) {
933  if (new->a_family != neigh->n_family)
934  return -NLE_AF_MISMATCH;
935  } else {
936  neigh->n_family = new->a_family;
937  neigh->ce_mask |= NEIGH_ATTR_FAMILY;
938  }
939  }
940 
941  if (*pos)
942  nl_addr_put(*pos);
943 
944  nl_addr_get(new);
945  *pos = new;
946 
947  neigh->ce_mask |= flag;
948 
949  return 0;
950 }
951 
952 void rtnl_neigh_set_lladdr(struct rtnl_neigh *neigh, struct nl_addr *addr)
953 {
954  __assign_addr(neigh, &neigh->n_lladdr, addr, NEIGH_ATTR_LLADDR, 1);
955 }
956 
957 struct nl_addr *rtnl_neigh_get_lladdr(struct rtnl_neigh *neigh)
958 {
959  if (neigh->ce_mask & NEIGH_ATTR_LLADDR)
960  return neigh->n_lladdr;
961  else
962  return NULL;
963 }
964 
965 int rtnl_neigh_set_dst(struct rtnl_neigh *neigh, struct nl_addr *addr)
966 {
967  return __assign_addr(neigh, &neigh->n_dst, addr,
968  NEIGH_ATTR_DST, 0);
969 }
970 
971 struct nl_addr *rtnl_neigh_get_dst(struct rtnl_neigh *neigh)
972 {
973  if (neigh->ce_mask & NEIGH_ATTR_DST)
974  return neigh->n_dst;
975  else
976  return NULL;
977 }
978 
979 void rtnl_neigh_set_family(struct rtnl_neigh *neigh, int family)
980 {
981  neigh->n_family = family;
982  neigh->ce_mask |= NEIGH_ATTR_FAMILY;
983 }
984 
985 int rtnl_neigh_get_family(struct rtnl_neigh *neigh)
986 {
987  return neigh->n_family;
988 }
989 
990 void rtnl_neigh_set_type(struct rtnl_neigh *neigh, int type)
991 {
992  neigh->n_type = type;
993  neigh->ce_mask = NEIGH_ATTR_TYPE;
994 }
995 
996 int rtnl_neigh_get_type(struct rtnl_neigh *neigh)
997 {
998  if (neigh->ce_mask & NEIGH_ATTR_TYPE)
999  return neigh->n_type;
1000  else
1001  return -1;
1002 }
1003 
1004 void rtnl_neigh_set_vlan(struct rtnl_neigh *neigh, int vlan)
1005 {
1006  neigh->n_vlan = vlan;
1007  neigh->ce_mask |= NEIGH_ATTR_VLAN;
1008 }
1009 
1010 int rtnl_neigh_get_vlan(struct rtnl_neigh *neigh)
1011 {
1012  if (neigh->ce_mask & NEIGH_ATTR_VLAN)
1013  return neigh->n_vlan;
1014  else
1015  return -1;
1016 }
1017 
1018 /** @} */
1019 
1020 static struct nl_object_ops neigh_obj_ops = {
1021  .oo_name = "route/neigh",
1022  .oo_size = sizeof(struct rtnl_neigh),
1023  .oo_free_data = neigh_free_data,
1024  .oo_clone = neigh_clone,
1025  .oo_dump = {
1026  [NL_DUMP_LINE] = neigh_dump_line,
1027  [NL_DUMP_DETAILS] = neigh_dump_details,
1028  [NL_DUMP_STATS] = neigh_dump_stats,
1029  },
1030  .oo_compare = neigh_compare,
1031  .oo_keygen = neigh_keygen,
1032  .oo_attrs2str = neigh_attrs2str,
1033  .oo_id_attrs = (NEIGH_ATTR_IFINDEX | NEIGH_ATTR_DST | NEIGH_ATTR_FAMILY),
1034  .oo_id_attrs_get = neigh_id_attrs_get
1035 };
1036 
1037 static struct nl_af_group neigh_groups[] = {
1038  { AF_UNSPEC, RTNLGRP_NEIGH },
1039  { AF_BRIDGE, RTNLGRP_NEIGH },
1040  { END_OF_GROUP_LIST },
1041 };
1042 
1043 static struct nl_cache_ops rtnl_neigh_ops = {
1044  .co_name = "route/neigh",
1045  .co_hdrsize = sizeof(struct ndmsg),
1046  .co_msgtypes = {
1047  { RTM_NEWNEIGH, NL_ACT_NEW, "new" },
1048  { RTM_DELNEIGH, NL_ACT_DEL, "del" },
1049  { RTM_GETNEIGH, NL_ACT_GET, "get" },
1050  END_OF_MSGTYPES_LIST,
1051  },
1052  .co_protocol = NETLINK_ROUTE,
1053  .co_groups = neigh_groups,
1054  .co_request_update = neigh_request_update,
1055  .co_msg_parser = neigh_msg_parser,
1056  .co_obj_ops = &neigh_obj_ops,
1057 };
1058 
1059 static void __init neigh_init(void)
1060 {
1061  nl_cache_mngt_register(&rtnl_neigh_ops);
1062 }
1063 
1064 static void __exit neigh_exit(void)
1065 {
1066  nl_cache_mngt_unregister(&rtnl_neigh_ops);
1067 }
1068 
1069 /** @} */
int nl_send_auto_complete(struct nl_sock *sk, struct nl_msg *msg)
Definition: nl.c:1247
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:508
void nlmsg_free(struct nl_msg *msg)
Release a reference from an netlink message.
Definition: msg.c:562
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:793
void * nlmsg_data(const struct nlmsghdr *nlh)
Return pointer to message payload.
Definition: msg.c:106
#define NLA_PUT_ADDR(msg, attrtype, addr)
Add address attribute to netlink message.
Definition: attr.h:288
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: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: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:569
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:623
uint32_t nla_get_u32(const struct nlattr *nla)
Return payload of 32 bit integer attribute.
Definition: attr.c:706
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:214
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:844
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:738
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:598
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:775
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:714
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:553
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:446
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:1040
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:347
uint16_t nla_get_u16(const struct nlattr *nla)
Return payload of 16 bit integer attribute.
Definition: attr.c:656
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:217
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:961
unsigned int nl_addr_get_len(const struct nl_addr *addr)
Get length of binary address of abstract address object.
Definition: addr.c:917
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:905
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:963
int nl_addr_get_family(const struct nl_addr *addr)
Return address family.
Definition: addr.c:857