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