summaryrefslogtreecommitdiff
path: root/zebra/rt_netlink.c
diff options
context:
space:
mode:
authorPhilippe Guibert <philippe.guibert@6wind.com>2019-12-12 16:06:59 +0100
committerPhilippe Guibert <philippe.guibert@6wind.com>2021-04-09 18:29:58 +0200
commit7723e8d3fd86a2e00b99df6fbb64083c23c1e637 (patch)
treefd558e4e24409dc4487ae53ca6ec98e487b48ce7 /zebra/rt_netlink.c
parentfda64ab443f498e00b9b229772dddf08b595b470 (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.c33
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. */