diff options
| author | Philippe Guibert <philippe.guibert@6wind.com> | 2019-12-12 16:06:59 +0100 |
|---|---|---|
| committer | Philippe Guibert <philippe.guibert@6wind.com> | 2021-04-09 18:29:58 +0200 |
| commit | 7723e8d3fd86a2e00b99df6fbb64083c23c1e637 (patch) | |
| tree | fd558e4e24409dc4487ae53ca6ec98e487b48ce7 /zebra/rt_netlink.c | |
| parent | fda64ab443f498e00b9b229772dddf08b595b470 (diff) | |
zebra: link layer config and notification, implementation in zebra
zebra implements zebra api for configuring link layer information. that
can be an arp entry (for ipv4) or ipv6 neighbor discovery entry. This
can also be an ipv4/ipv6 entry associated to an underlay ipv4 address,
as it is used in gre point to multipoint interfaces.
this api will also be used as monitoring. an hash list is instantiated
into zebra (this is the vrf bitmap). each client interested in those entries
in a specific vrf, will listen for following messages: entries added, removed,
or who-has messages.
Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
Diffstat (limited to 'zebra/rt_netlink.c')
| -rw-r--r-- | zebra/rt_netlink.c | 33 |
1 files changed, 32 insertions, 1 deletions
diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index 55e0775a8c..82ef78d299 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -3307,6 +3307,8 @@ static int netlink_ipneigh_change(struct nlmsghdr *h, int len, ns_id_t ns_id) bool local_inactive; uint32_t ext_flags = 0; bool dp_static = false; + int l2_len = 0; + int cmd; ndm = NLMSG_DATA(h); @@ -3348,6 +3350,34 @@ static int netlink_ipneigh_change(struct nlmsghdr *h, int len, ns_id_t ns_id) if (h->nlmsg_type == RTM_NEWNEIGH && !(ndm->ndm_state & NUD_VALID)) netlink_handle_5549(ndm, zif, ifp, &ip, true); + /* we send link layer information to client: + * - nlmsg_type = RTM_DELNEIGH|NEWNEIGH|GETNEIGH + * - struct ipaddr ( for DEL and GET) + * - struct ethaddr mac; (for NEW) + */ + if (h->nlmsg_type == RTM_NEWNEIGH) + cmd = ZEBRA_NHRP_NEIGH_ADDED; + else if (h->nlmsg_type == RTM_GETNEIGH) + cmd = ZEBRA_NHRP_NEIGH_GET; + else if (h->nlmsg_type == RTM_DELNEIGH) + cmd = ZEBRA_NHRP_NEIGH_REMOVED; + else { + zlog_debug("%s(): unknown nlmsg type %u", __func__, + h->nlmsg_type); + return 0; + } + if (tb[NDA_LLADDR]) { + /* copy LLADDR information */ + l2_len = RTA_PAYLOAD(tb[NDA_LLADDR]); + memcpy(&mac, RTA_DATA(tb[NDA_LLADDR]), l2_len); + } + if (l2_len == IPV4_MAX_BYTELEN || l2_len == 0) + zsend_nhrp_neighbor_notify(cmd, ifp, &ip, ndm->ndm_state, + &mac, l2_len); + + if (h->nlmsg_type == RTM_GETNEIGH) + return 0; + /* The neighbor is present on an SVI. From this, we locate the * underlying * bridge because we're only interested in neighbors on a VxLAN bridge. @@ -3615,7 +3645,8 @@ int netlink_neigh_change(struct nlmsghdr *h, ns_id_t ns_id) int len; struct ndmsg *ndm; - if (!(h->nlmsg_type == RTM_NEWNEIGH || h->nlmsg_type == RTM_DELNEIGH)) + if (!(h->nlmsg_type == RTM_NEWNEIGH || h->nlmsg_type == RTM_DELNEIGH + || h->nlmsg_type == RTM_GETNEIGH)) return 0; /* Length validity. */ |
