146#include "nl-default.h"
148#include <netlink/netlink.h>
149#include <netlink/utils.h>
150#include <netlink/hashtable.h>
151#include <netlink/route/rtnl.h>
152#include <netlink/route/neighbour.h>
153#include <netlink/route/link.h>
154#include <netlink/hashtable.h>
157#include "nl-priv-dynamic-core/nl-core.h"
158#include "nl-priv-dynamic-core/cache-api.h"
161struct rtnl_ncacheinfo {
162 uint32_t nci_confirmed;
164 uint32_t nci_updated;
174 uint32_t n_ext_flags;
176 struct nl_addr *n_lladdr;
177 struct nl_addr *n_dst;
180 struct rtnl_ncacheinfo n_cacheinfo;
181 uint32_t n_state_mask;
182 uint32_t n_flag_mask;
183 uint32_t n_ext_flag_mask;
188#define NEIGH_ATTR_FLAGS 0x01
189#define NEIGH_ATTR_STATE 0x02
190#define NEIGH_ATTR_LLADDR 0x04
191#define NEIGH_ATTR_DST 0x08
192#define NEIGH_ATTR_CACHEINFO 0x10
193#define NEIGH_ATTR_IFINDEX 0x20
194#define NEIGH_ATTR_FAMILY 0x40
195#define NEIGH_ATTR_TYPE 0x80
196#define NEIGH_ATTR_PROBES 0x0100
197#define NEIGH_ATTR_MASTER 0x0200
198#define NEIGH_ATTR_VLAN 0x0400
199#define NEIGH_ATTR_NHID 0x0800
200#define NEIGH_ATTR_EXT_FLAGS 0x1000
202static struct nl_cache_ops rtnl_neigh_ops;
203static struct nl_object_ops neigh_obj_ops;
206static void neigh_free_data(
struct nl_object *c)
208 struct rtnl_neigh *neigh = nl_object_priv(c);
217static int neigh_clone(
struct nl_object *_dst,
struct nl_object *_src)
219 struct rtnl_neigh *dst = nl_object_priv(_dst);
220 struct rtnl_neigh *src = nl_object_priv(_src);
222 dst->n_lladdr = NULL;
236static void neigh_keygen(
struct nl_object *obj, uint32_t *hashkey,
239 struct rtnl_neigh *neigh = (
struct rtnl_neigh *) obj;
240 unsigned int nkey_sz;
241 struct nl_addr *addr = NULL;
242 struct neigh_hash_key {
248 char buf[INET6_ADDRSTRLEN+5];
250 if (neigh->n_family == AF_BRIDGE) {
252 addr = neigh->n_lladdr;
253 }
else if (neigh->n_dst) {
257 nkey_sz =
sizeof(*nkey);
261 nkey = calloc(1, nkey_sz);
266 nkey->n_family = neigh->n_family;
267 if (neigh->n_family == AF_BRIDGE) {
268 nkey->n_vlan = neigh->n_vlan;
269 if (neigh->n_flags & NTF_SELF)
270 nkey->n_ifindex = neigh->n_ifindex;
272 nkey->n_ifindex = neigh->n_master;
274 nkey->n_ifindex = neigh->n_ifindex;
281 *hashkey = nl_hash(nkey, nkey_sz, 0) % table_sz;
283 NL_DBG(5,
"neigh %p key (fam %d dev %d addr %s) keysz %d hash 0x%x\n",
284 neigh, nkey->n_family, nkey->n_ifindex,
293static uint64_t neigh_compare(
struct nl_object *_a,
struct nl_object *_b,
294 uint64_t attrs,
int flags)
296 struct rtnl_neigh *a = (
struct rtnl_neigh *) _a;
297 struct rtnl_neigh *b = (
struct rtnl_neigh *) _b;
300#define _DIFF(ATTR, EXPR) ATTR_DIFF(attrs, ATTR, a, b, EXPR)
301 diff |= _DIFF(NEIGH_ATTR_IFINDEX, a->n_ifindex != b->n_ifindex);
302 diff |= _DIFF(NEIGH_ATTR_FAMILY, a->n_family != b->n_family);
303 diff |= _DIFF(NEIGH_ATTR_TYPE, a->n_type != b->n_type);
304 diff |= _DIFF(NEIGH_ATTR_LLADDR,
nl_addr_cmp(a->n_lladdr, b->n_lladdr));
305 diff |= _DIFF(NEIGH_ATTR_DST,
nl_addr_cmp(a->n_dst, b->n_dst));
306 diff |= _DIFF(NEIGH_ATTR_MASTER, a->n_master != b->n_master);
307 diff |= _DIFF(NEIGH_ATTR_VLAN, a->n_vlan != b->n_vlan);
308 diff |= _DIFF(NEIGH_ATTR_NHID, a->n_nhid != b->n_nhid);
310 if (flags & LOOSE_COMPARISON) {
311 diff |= _DIFF(NEIGH_ATTR_STATE,
312 (a->n_state ^ b->n_state) & b->n_state_mask);
313 diff |= _DIFF(NEIGH_ATTR_FLAGS,
314 (a->n_flags ^ b->n_flags) & b->n_flag_mask);
315 diff |= _DIFF(NEIGH_ATTR_EXT_FLAGS,
316 (a->n_ext_flags ^ b->n_ext_flags) & b->n_ext_flag_mask);
318 diff |= _DIFF(NEIGH_ATTR_STATE, a->n_state != b->n_state);
319 diff |= _DIFF(NEIGH_ATTR_FLAGS, a->n_flags != b->n_flags);
320 diff |= _DIFF(NEIGH_ATTR_EXT_FLAGS, a->n_ext_flags != b->n_ext_flags);
327static const struct trans_tbl neigh_attrs[] = {
328 __ADD(NEIGH_ATTR_FLAGS, flags),
329 __ADD(NEIGH_ATTR_STATE, state),
330 __ADD(NEIGH_ATTR_LLADDR, lladdr),
331 __ADD(NEIGH_ATTR_DST, dst),
332 __ADD(NEIGH_ATTR_CACHEINFO, cacheinfo),
333 __ADD(NEIGH_ATTR_IFINDEX, ifindex),
334 __ADD(NEIGH_ATTR_FAMILY, family),
335 __ADD(NEIGH_ATTR_TYPE, type),
336 __ADD(NEIGH_ATTR_PROBES, probes),
337 __ADD(NEIGH_ATTR_MASTER, master),
338 __ADD(NEIGH_ATTR_VLAN, vlan),
339 __ADD(NEIGH_ATTR_NHID, nhid),
340 __ADD(NEIGH_ATTR_EXT_FLAGS, ext_flags),
343static char *neigh_attrs2str(
int attrs,
char *buf,
size_t len)
345 return __flags2str(attrs, buf, len, neigh_attrs,
346 ARRAY_SIZE(neigh_attrs));
349static uint32_t neigh_id_attrs_get(
struct nl_object *obj)
351 struct rtnl_neigh *neigh = (
struct rtnl_neigh *)obj;
353 if (neigh->n_family == AF_BRIDGE) {
354 if (neigh->n_flags & NTF_SELF)
355 return (NEIGH_ATTR_LLADDR | NEIGH_ATTR_FAMILY | NEIGH_ATTR_IFINDEX |
356 ((neigh->ce_mask & NEIGH_ATTR_DST) ? NEIGH_ATTR_DST: 0) |
357 ((neigh->ce_mask & NEIGH_ATTR_NHID) ? NEIGH_ATTR_NHID: 0) |
358 ((neigh->ce_mask & NEIGH_ATTR_VLAN) ? NEIGH_ATTR_VLAN : 0));
360 return (NEIGH_ATTR_LLADDR | NEIGH_ATTR_FAMILY | NEIGH_ATTR_MASTER | NEIGH_ATTR_VLAN);
362 return neigh_obj_ops.oo_id_attrs;
367 [NDA_PROBES] = { .type =
NLA_U32 },
370static int neigh_msg_parser(
struct nl_cache_ops *ops,
struct sockaddr_nl *who,
371 struct nlmsghdr *n,
struct nl_parser_param *pp)
373 struct rtnl_neigh *neigh;
376 if ((err = rtnl_neigh_parse(n, &neigh)) < 0)
379 err = pp->pp_cb((
struct nl_object *) neigh, pp);
381 rtnl_neigh_put(neigh);
386int rtnl_neigh_parse(
struct nlmsghdr *n,
struct rtnl_neigh **result)
388 struct rtnl_neigh *neigh;
389 struct nlattr *tb[NDA_MAX + 1];
393 neigh = rtnl_neigh_alloc();
399 neigh->ce_msgtype = n->nlmsg_type;
402 err =
nlmsg_parse(n,
sizeof(*nm), tb, NDA_MAX, neigh_policy);
406 neigh->n_family = nm->ndm_family;
407 neigh->n_ifindex = nm->ndm_ifindex;
408 neigh->n_state = nm->ndm_state;
409 neigh->n_flags = nm->ndm_flags;
410 neigh->n_type = nm->ndm_type;
412 neigh->ce_mask |= (NEIGH_ATTR_FAMILY | NEIGH_ATTR_IFINDEX |
413 NEIGH_ATTR_STATE | NEIGH_ATTR_FLAGS |
416 if (tb[NDA_LLADDR]) {
418 if (!neigh->n_lladdr) {
424 neigh->ce_mask |= NEIGH_ATTR_LLADDR;
435 neigh->ce_mask |= NEIGH_ATTR_DST;
438 if (tb[NDA_CACHEINFO]) {
439 struct nda_cacheinfo *ci =
nla_data(tb[NDA_CACHEINFO]);
441 neigh->n_cacheinfo.nci_confirmed = ci->ndm_confirmed;
442 neigh->n_cacheinfo.nci_used = ci->ndm_used;
443 neigh->n_cacheinfo.nci_updated = ci->ndm_updated;
444 neigh->n_cacheinfo.nci_refcnt = ci->ndm_refcnt;
446 neigh->ce_mask |= NEIGH_ATTR_CACHEINFO;
449 if (tb[NDA_PROBES]) {
451 neigh->ce_mask |= NEIGH_ATTR_PROBES;
456 neigh->ce_mask |= NEIGH_ATTR_VLAN;
461 neigh->ce_mask |= NEIGH_ATTR_NHID;
464 if (tb[NDA_FLAGS_EXT]) {
465 neigh->n_ext_flags =
nla_get_u32(tb[NDA_FLAGS_EXT]);
466 neigh->ce_mask |= NEIGH_ATTR_EXT_FLAGS;
472 if (neigh->n_family == AF_BRIDGE) {
473 if (tb[NDA_MASTER]) {
475 neigh->ce_mask |= NEIGH_ATTR_MASTER;
482 neigh->n_master = link->l_master;
484 neigh->ce_mask |= NEIGH_ATTR_MASTER;
486 nl_cache_put(lcache);
495 rtnl_neigh_put(neigh);
499static int neigh_request_update(
struct nl_cache *c,
struct nl_sock *h)
501 int family = c->c_iarg1;
503 if (family == AF_UNSPEC) {
505 }
else if (family == AF_BRIDGE) {
506 struct ifinfomsg hdr = {.ifi_family = family};
515 if (
nlmsg_append(msg, &hdr,
sizeof(hdr), NLMSG_ALIGNTO) < 0)
516 goto nla_put_failure;
531static void neigh_dump_line(
struct nl_object *a,
struct nl_dump_params *p)
533 char dst[INET6_ADDRSTRLEN+5], lladdr[INET6_ADDRSTRLEN+5];
534 struct rtnl_neigh *n = (
struct rtnl_neigh *) a;
535 struct nl_cache *link_cache;
536 char state[128], flags[64], ext_flags[64];
541 if (n->n_family != AF_UNSPEC)
542 nl_dump_line(p,
"%s ", nl_af2str(n->n_family, buf,
sizeof(buf)));
544 if (n->ce_mask & NEIGH_ATTR_DST)
545 nl_dump_line(p,
"%s ",
nl_addr2str(n->n_dst, dst,
sizeof(dst)));
550 state,
sizeof(state)));
552 nl_dump(p,
"dev %d ", n->n_ifindex);
554 if (n->ce_mask & NEIGH_ATTR_LLADDR)
558 if (n->ce_mask & NEIGH_ATTR_VLAN)
559 nl_dump(p,
"vlan %d ", n->n_vlan);
561 if (n->ce_mask & NEIGH_ATTR_NHID)
562 nl_dump(p,
"nhid %u ", n->n_nhid);
564 if (n->ce_mask & NEIGH_ATTR_MASTER) {
567 state,
sizeof(state)));
569 nl_dump(p,
"%d ", n->n_master);
572 rtnl_neigh_state2str(n->n_state, state,
sizeof(state));
573 rtnl_neigh_flags2str(n->n_flags, flags,
sizeof(flags));
574 rtnl_neigh_extflags2str(n->n_ext_flags, ext_flags,
sizeof(ext_flags));
579 nl_dump(p,
"%s%s", state[0] ?
"," :
"<", flags);
581 nl_dump(p,
"%s%s", state[0] || flags[0] ?
"," :
"<", ext_flags);
582 if (state[0] || flags[0] || ext_flags[0])
587 nl_cache_put(link_cache);
590static void neigh_dump_details(
struct nl_object *a,
struct nl_dump_params *p)
593 struct rtnl_neigh *n = (
struct rtnl_neigh *) a;
596 neigh_dump_line(a, p);
598 nl_dump_line(p,
" refcnt %u type %s confirmed %u used "
600 n->n_cacheinfo.nci_refcnt,
601 nl_rtntype2str(n->n_type, rtn_type,
sizeof(rtn_type)),
602 n->n_cacheinfo.nci_confirmed/hz,
603 n->n_cacheinfo.nci_used/hz, n->n_cacheinfo.nci_updated/hz);
606static void neigh_dump_stats(
struct nl_object *a,
struct nl_dump_params *p)
608 neigh_dump_details(a, p);
616struct rtnl_neigh *rtnl_neigh_alloc(
void)
621void rtnl_neigh_put(
struct rtnl_neigh *neigh)
662 struct nl_cache * cache;
691 struct rtnl_neigh *neigh;
693 nl_list_for_each_entry(neigh, &cache->c_items, ce_list) {
694 if (neigh->n_ifindex == ((
unsigned)ifindex) &&
695 neigh->n_family == ((
unsigned)dst->a_family) &&
715 struct nl_addr *lladdr,
int vlan)
717 struct rtnl_neigh *neigh;
719 nl_list_for_each_entry(neigh, &cache->c_items, ce_list) {
720 if ((neigh->n_ifindex == (
unsigned)ifindex) &&
721 neigh->n_vlan == vlan && neigh->n_lladdr &&
738static int build_neigh_msg(
struct rtnl_neigh *tmpl,
int cmd,
int flags,
739 struct nl_msg **result)
742 struct ndmsg nhdr = {
743 .ndm_ifindex = tmpl->n_ifindex,
744 .ndm_state = NUD_PERMANENT,
747 if (tmpl->n_family != AF_BRIDGE) {
748 if (!(tmpl->ce_mask & NEIGH_ATTR_DST))
749 return -NLE_MISSING_ATTR;
753 nhdr.ndm_family = AF_BRIDGE;
755 if (tmpl->ce_mask & NEIGH_ATTR_FLAGS)
756 nhdr.ndm_flags = tmpl->n_flags;
758 if (tmpl->ce_mask & NEIGH_ATTR_STATE)
759 nhdr.ndm_state = tmpl->n_state;
765 if (
nlmsg_append(msg, &nhdr,
sizeof(nhdr), NLMSG_ALIGNTO) < 0)
766 goto nla_put_failure;
768 if (tmpl->ce_mask & NEIGH_ATTR_DST)
771 if (tmpl->ce_mask & NEIGH_ATTR_LLADDR)
774 if (tmpl->ce_mask & NEIGH_ATTR_VLAN)
777 if (tmpl->ce_mask & NEIGH_ATTR_NHID)
780 if (tmpl->ce_mask & NEIGH_ATTR_EXT_FLAGS) {
783 uint32_t ext_flags = tmpl->n_ext_flags &
784 ~(uint32_t)NTF_EXT_LOCKED;
819 struct nl_msg **result)
821 return build_neigh_msg(tmpl, RTM_NEWNEIGH, flags, result);
855 return wait_for_ack(sk);
880 struct nl_msg **result)
882 return build_neigh_msg(neigh, RTM_DELNEIGH, flags, result);
911 return wait_for_ack(sk);
921static const struct trans_tbl neigh_states[] = {
922 __ADD(NUD_INCOMPLETE, incomplete),
923 __ADD(NUD_REACHABLE, reachable),
924 __ADD(NUD_STALE, stale),
925 __ADD(NUD_DELAY, delay),
926 __ADD(NUD_PROBE, probe),
927 __ADD(NUD_FAILED, failed),
928 __ADD(NUD_NOARP, noarp),
929 __ADD(NUD_PERMANENT, permanent),
934 __ADD(NUD_NOARP, norarp),
937char * rtnl_neigh_state2str(
int state,
char *buf,
size_t len)
939 return __flags2str(state, buf, len, neigh_states,
940 ARRAY_SIZE(neigh_states) - 1);
943int rtnl_neigh_str2state(
const char *name)
945 return __str2type(name, neigh_states, ARRAY_SIZE(neigh_states));
955static const struct trans_tbl neigh_flags[] = {
957 __ADD(NTF_PROXY, proxy),
958 __ADD(NTF_ROUTER, router),
959 __ADD(NTF_SELF, self),
960 __ADD(NTF_MASTER, master),
961 __ADD(NTF_EXT_LEARNED, ext_learned),
962 __ADD(NTF_OFFLOADED, offloaded),
965static const struct trans_tbl neigh_ext_flags[] = {
966 __ADD(NTF_EXT_MANAGED, managed),
967 __ADD(NTF_EXT_LOCKED, locked),
970char * rtnl_neigh_flags2str(
int flags,
char *buf,
size_t len)
972 return __flags2str(flags, buf, len, neigh_flags,
973 ARRAY_SIZE(neigh_flags));
976int rtnl_neigh_str2flag(
const char *name)
978 return __str2type(name, neigh_flags, ARRAY_SIZE(neigh_flags));
981char * rtnl_neigh_extflags2str(uint32_t flags,
char *buf,
size_t len)
983 return __flags2str(flags, buf, len, neigh_ext_flags,
984 ARRAY_SIZE(neigh_ext_flags));
987uint32_t rtnl_neigh_str2extflag(
const char *name)
989 return __str2type(name, neigh_ext_flags, ARRAY_SIZE(neigh_ext_flags));
999void rtnl_neigh_set_state(
struct rtnl_neigh *neigh,
int state)
1001 neigh->n_state_mask |= state;
1002 neigh->n_state |= state;
1003 neigh->ce_mask |= NEIGH_ATTR_STATE;
1006int rtnl_neigh_get_state(
struct rtnl_neigh *neigh)
1008 if (neigh->ce_mask & NEIGH_ATTR_STATE)
1009 return neigh->n_state;
1014void rtnl_neigh_unset_state(
struct rtnl_neigh *neigh,
int state)
1016 neigh->n_state_mask |= state;
1017 neigh->n_state &= ~state;
1018 neigh->ce_mask |= NEIGH_ATTR_STATE;
1021void rtnl_neigh_set_flags(
struct rtnl_neigh *neigh,
unsigned int flags)
1023 neigh->n_flag_mask |= flags;
1024 neigh->n_flags |= flags;
1025 neigh->ce_mask |= NEIGH_ATTR_FLAGS;
1028unsigned int rtnl_neigh_get_flags(
struct rtnl_neigh *neigh)
1030 return neigh->n_flags;
1033void rtnl_neigh_unset_flags(
struct rtnl_neigh *neigh,
unsigned int flags)
1035 neigh->n_flag_mask |= flags;
1036 neigh->n_flags &= ~flags;
1037 neigh->ce_mask |= NEIGH_ATTR_FLAGS;
1040void rtnl_neigh_set_ext_flags(
struct rtnl_neigh *neigh, uint32_t ext_flags)
1042 neigh->n_ext_flag_mask |= ext_flags;
1043 neigh->n_ext_flags |= ext_flags;
1044 neigh->ce_mask |= NEIGH_ATTR_EXT_FLAGS;
1047int rtnl_neigh_get_ext_flags(
struct rtnl_neigh *neigh, uint32_t *out_val)
1049 if (!(neigh->ce_mask & NEIGH_ATTR_EXT_FLAGS))
1052 *out_val = neigh->n_ext_flags;
1056void rtnl_neigh_unset_ext_flags(
struct rtnl_neigh *neigh, uint32_t ext_flags)
1058 neigh->n_ext_flag_mask |= ext_flags;
1059 neigh->n_ext_flags &= ~ext_flags;
1060 neigh->ce_mask |= NEIGH_ATTR_EXT_FLAGS;
1063void rtnl_neigh_set_ifindex(
struct rtnl_neigh *neigh,
int ifindex)
1065 neigh->n_ifindex = ifindex;
1066 neigh->ce_mask |= NEIGH_ATTR_IFINDEX;
1069int rtnl_neigh_get_ifindex(
struct rtnl_neigh *neigh)
1071 return neigh->n_ifindex;
1074static inline int __assign_addr(
struct rtnl_neigh *neigh,
struct nl_addr **pos,
1075 struct nl_addr *
new,
int flag,
int nocheck)
1078 if (neigh->ce_mask & NEIGH_ATTR_FAMILY) {
1079 if (neigh->n_family != ((
unsigned)new->a_family))
1080 return -NLE_AF_MISMATCH;
1082 neigh->n_family =
new->a_family;
1083 neigh->ce_mask |= NEIGH_ATTR_FAMILY;
1093 neigh->ce_mask |= flag;
1098void rtnl_neigh_set_lladdr(
struct rtnl_neigh *neigh,
struct nl_addr *addr)
1100 __assign_addr(neigh, &neigh->n_lladdr, addr, NEIGH_ATTR_LLADDR, 1);
1103struct nl_addr *rtnl_neigh_get_lladdr(
struct rtnl_neigh *neigh)
1105 if (neigh->ce_mask & NEIGH_ATTR_LLADDR)
1106 return neigh->n_lladdr;
1111int rtnl_neigh_set_dst(
struct rtnl_neigh *neigh,
struct nl_addr *addr)
1113 return __assign_addr(neigh, &neigh->n_dst, addr,
1117struct nl_addr *rtnl_neigh_get_dst(
struct rtnl_neigh *neigh)
1119 if (neigh->ce_mask & NEIGH_ATTR_DST)
1120 return neigh->n_dst;
1125void rtnl_neigh_set_family(
struct rtnl_neigh *neigh,
int family)
1127 neigh->n_family = family;
1128 neigh->ce_mask |= NEIGH_ATTR_FAMILY;
1131int rtnl_neigh_get_family(
struct rtnl_neigh *neigh)
1133 return neigh->n_family;
1136void rtnl_neigh_set_type(
struct rtnl_neigh *neigh,
int type)
1138 neigh->n_type = type;
1139 neigh->ce_mask = NEIGH_ATTR_TYPE;
1142int rtnl_neigh_get_type(
struct rtnl_neigh *neigh)
1144 if (neigh->ce_mask & NEIGH_ATTR_TYPE)
1145 return neigh->n_type;
1150void rtnl_neigh_set_vlan(
struct rtnl_neigh *neigh,
int vlan)
1152 neigh->n_vlan = vlan;
1153 neigh->ce_mask |= NEIGH_ATTR_VLAN;
1156int rtnl_neigh_get_vlan(
struct rtnl_neigh *neigh)
1158 if (neigh->ce_mask & NEIGH_ATTR_VLAN)
1159 return neigh->n_vlan;
1164void rtnl_neigh_set_master(
struct rtnl_neigh *neigh,
int ifindex)
1166 neigh->n_master = ifindex;
1167 neigh->ce_mask |= NEIGH_ATTR_MASTER;
1170int rtnl_neigh_get_master(
struct rtnl_neigh *neigh) {
1171 return neigh->n_master;
1174void rtnl_neigh_set_nhid(
struct rtnl_neigh *neigh, uint32_t nhid)
1176 neigh->n_nhid = nhid;
1177 neigh->ce_mask |= NEIGH_ATTR_NHID;
1180int rtnl_neigh_get_nhid(
struct rtnl_neigh *neigh, uint32_t *out_val) {
1181 if (!(neigh->ce_mask & NEIGH_ATTR_NHID))
1184 *out_val = neigh->n_nhid;
1190static struct nl_object_ops neigh_obj_ops = {
1191 .oo_name =
"route/neigh",
1192 .oo_size =
sizeof(
struct rtnl_neigh),
1193 .oo_free_data = neigh_free_data,
1194 .oo_clone = neigh_clone,
1200 .oo_compare = neigh_compare,
1201 .oo_keygen = neigh_keygen,
1202 .oo_attrs2str = neigh_attrs2str,
1203 .oo_id_attrs = (NEIGH_ATTR_IFINDEX | NEIGH_ATTR_DST | NEIGH_ATTR_FAMILY),
1204 .oo_id_attrs_get = neigh_id_attrs_get
1207static struct nl_af_group neigh_groups[] = {
1208 { AF_UNSPEC, RTNLGRP_NEIGH },
1209 { AF_BRIDGE, RTNLGRP_NEIGH },
1210 { END_OF_GROUP_LIST },
1213static struct nl_cache_ops rtnl_neigh_ops = {
1214 .co_name =
"route/neigh",
1215 .co_hdrsize =
sizeof(
struct ndmsg),
1217 { RTM_NEWNEIGH, NL_ACT_NEW,
"new" },
1218 { RTM_DELNEIGH, NL_ACT_DEL,
"del" },
1219 { RTM_GETNEIGH, NL_ACT_GET,
"get" },
1220 END_OF_MSGTYPES_LIST,
1222 .co_protocol = NETLINK_ROUTE,
1223 .co_groups = neigh_groups,
1224 .co_request_update = neigh_request_update,
1225 .co_msg_parser = neigh_msg_parser,
1226 .co_obj_ops = &neigh_obj_ops,
1229static void _nl_init neigh_init(
void)
1234static void _nl_exit neigh_exit(
void)
struct nl_addr * nl_addr_get(struct nl_addr *addr)
Increase the reference counter of an abstract address.
struct nl_addr * nl_addr_alloc_attr(const struct nlattr *nla, int family)
Allocate abstract address based on Netlink attribute.
void * nl_addr_get_binary_addr(const struct nl_addr *addr)
Get binary address of abstract address object.
int nl_addr_cmp(const struct nl_addr *a, const struct nl_addr *b)
Compare abstract addresses.
struct nl_addr * nl_addr_clone(const struct nl_addr *addr)
Clone existing abstract address object.
int nl_addr_get_family(const struct nl_addr *addr)
Return address family.
char * nl_addr2str(const struct nl_addr *addr, char *buf, size_t size)
Convert abstract address object to character string.
unsigned int nl_addr_get_len(const struct nl_addr *addr)
Get length of binary address of abstract address object.
void nl_addr_put(struct nl_addr *addr)
Decrease the reference counter of an abstract address.
void nl_addr_set_family(struct nl_addr *addr, int family)
Set address family.
int nl_addr_guess_family(const struct nl_addr *addr)
Guess address family of abstract address based on address size.
uint32_t nla_get_u32(const struct nlattr *nla)
Return payload of 32 bit integer attribute.
uint16_t nla_get_u16(const struct nlattr *nla)
Return payload of 16 bit integer attribute.
#define NLA_PUT_U16(msg, attrtype, value)
Add 16 bit integer attribute to netlink message.
#define NLA_PUT_ADDR(msg, attrtype, addr)
Add address attribute to netlink message.
void * nla_data(const struct nlattr *nla)
Return pointer to the payload section.
#define NLA_PUT_U32(msg, attrtype, value)
Add 32 bit integer attribute to netlink message.
int nl_cache_mngt_unregister(struct nl_cache_ops *ops)
Unregister a set of cache operations.
int nl_cache_mngt_register(struct nl_cache_ops *ops)
Register a set of cache operations.
struct nl_cache * nl_cache_mngt_require_safe(const char *name)
Return cache previously provided via nl_cache_mngt_provide()
int nl_cache_refill(struct nl_sock *sk, struct nl_cache *cache)
(Re)fill a cache with the contents in the kernel.
void nl_cache_set_flags(struct nl_cache *cache, unsigned int flags)
Set cache flags.
void nl_cache_free(struct nl_cache *cache)
Free a cache.
struct nl_cache * nl_cache_alloc(struct nl_cache_ops *ops)
Allocate new cache.
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.
struct rtnl_link * rtnl_link_get(struct nl_cache *cache, int ifindex)
Lookup link in cache by interface index.
char * rtnl_link_i2name(struct nl_cache *cache, int ifindex, char *dst, size_t len)
Translate interface index to corresponding link name.
void rtnl_link_put(struct rtnl_link *link)
Release a link object reference.
struct nl_msg * nlmsg_alloc_simple(int nlmsgtype, int flags)
Allocate a new netlink message.
void * nlmsg_data(const struct nlmsghdr *nlh)
Return pointer to message payload.
void nlmsg_free(struct nl_msg *msg)
Release a reference from an netlink message.
int nlmsg_parse(struct nlmsghdr *nlh, int hdrlen, struct nlattr *tb[], int maxtype, const struct nla_policy *policy)
parse attributes of a netlink message
int nlmsg_append(struct nl_msg *n, void *data, size_t len, int pad)
Append data to tail of a netlink message.
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.
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.
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.
int rtnl_neigh_add(struct nl_sock *sk, struct rtnl_neigh *tmpl, int flags)
Add a new neighbour.
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.
int rtnl_neigh_delete(struct nl_sock *sk, struct rtnl_neigh *neigh, int flags)
Delete a neighbour.
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.
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.
void nl_object_put(struct nl_object *obj)
Release a reference from an object.
void nl_object_get(struct nl_object *obj)
Acquire a reference on a object.
struct nl_object * nl_object_alloc(struct nl_object_ops *ops)
Allocate a new object of kind specified by the operations handle.
int nl_rtgen_request(struct nl_sock *sk, int type, int family, int flags)
Send routing netlink request message.
int nl_send_auto(struct nl_sock *sk, struct nl_msg *msg)
Finalize and transmit Netlink message.
int nl_send_auto_complete(struct nl_sock *sk, struct nl_msg *msg)
int nl_get_user_hz(void)
Return the value of HZ.
void nl_dump(struct nl_dump_params *params, const char *fmt,...)
Dump a formatted character string.
@ NL_DUMP_STATS
Dump all attributes including statistics.
@ NL_DUMP_LINE
Dump object briefly on one line.
@ NL_DUMP_DETAILS
Dump all attributes but no statistics.
Attribute validation policy.
uint16_t minlen
Minimal length of payload required.
uint16_t type
Type of attribute or NLA_UNSPEC.