summaryrefslogtreecommitdiff
path: root/zebra/rt_netlink.c
diff options
context:
space:
mode:
authorvivek <vivek@cumulusnetworks.com>2017-05-15 14:42:57 -0700
committerDonald Sharp <sharpd@cumulusnetworks.com>2017-07-12 14:37:14 -0400
commitc85c03c7f90bfc6110c4621bfb096690c70b8bec (patch)
tree0430b6cca5448f0a38ec49d4a735378b112d72d4 /zebra/rt_netlink.c
parent128ea8abbd38eddd2a9bfa18b596acd95f081353 (diff)
bgpd, zebra: Support for sticky MACs
Implement support for sticky (static) MACs. This includes the following: - Recognize MAC is static (using NUD_NOARP flag) and inform BGP - Construct MAC mobility extended community for sticky MACs as per RFC 7432 section 15.2 - Inform to zebra that remote MAC is sticky, where appropriate - Install sticky MACs into the kernel with the right flag - Appropriate handling in route selection Signed-off-by: Daniel Walton <dwalton@cumulusnetworks.com> Reviewed-by: Vivek Venkatraman <vivek@cumulusnetworks.com> Reviewed-by: Donald Sharp <sharpd@cumulusnetworks.com>
Diffstat (limited to 'zebra/rt_netlink.c')
-rw-r--r--zebra/rt_netlink.c26
1 files changed, 18 insertions, 8 deletions
diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c
index 4be1e96ce5..d676fc8296 100644
--- a/zebra/rt_netlink.c
+++ b/zebra/rt_netlink.c
@@ -1658,6 +1658,7 @@ netlink_macfdb_change (struct sockaddr_nl *snl, struct nlmsghdr *h, int len)
char buf[ETHER_ADDR_STRLEN];
char vid_buf[20];
char dst_buf[30];
+ u_char sticky = 0;
ndm = NLMSG_DATA (h);
@@ -1738,12 +1739,15 @@ netlink_macfdb_change (struct sockaddr_nl *snl, struct nlmsghdr *h, int len)
sprintf (dst_buf, " dst %s", inet_ntoa (vtep_ip.u.prefix4));
}
+ sticky = (ndm->ndm_state & NUD_NOARP) ? 1 : 0;
+
if (IS_ZEBRA_DEBUG_KERNEL)
- zlog_debug ("Rx %s family %s IF %s(%u)%s MAC %s%s",
+ zlog_debug ("Rx %s family %s IF %s(%u)%s %sMAC %s%s",
nl_msg_type_to_str (h->nlmsg_type),
nl_family_to_str (ndm->ndm_family),
ifp->name, ndm->ndm_ifindex,
vid_present ? vid_buf : "",
+ sticky ? "sticky " : "",
prefix_mac2str (&mac, buf, sizeof (buf)),
dst_present ? dst_buf: "");
@@ -1763,7 +1767,7 @@ netlink_macfdb_change (struct sockaddr_nl *snl, struct nlmsghdr *h, int len)
if (IS_ZEBRA_IF_VXLAN(ifp))
return zebra_vxlan_check_del_local_mac (ifp, br_if, &mac, vid);
- return zebra_vxlan_local_mac_add_update (ifp, br_if, &mac, vid);
+ return zebra_vxlan_local_mac_add_update (ifp, br_if, &mac, vid, sticky);
}
/* This is a delete notification.
@@ -1884,7 +1888,8 @@ static int
netlink_macfdb_update (struct interface *ifp, vlanid_t vid,
struct ethaddr *mac,
struct in_addr vtep_ip,
- int local, int cmd)
+ int local, int cmd,
+ u_char sticky)
{
struct zebra_ns *zns = zebra_ns_lookup (NS_DEFAULT);
struct
@@ -1923,7 +1928,10 @@ netlink_macfdb_update (struct interface *ifp, vlanid_t vid,
req.ndm.ndm_flags |= NTF_SELF | NTF_MASTER;
req.ndm.ndm_state = NUD_REACHABLE;
- req.ndm.ndm_flags |= NTF_EXT_LEARNED;
+ if (sticky)
+ req.ndm.ndm_state |= NUD_NOARP;
+ else
+ req.ndm.ndm_flags |= NTF_EXT_LEARNED;
addattr_l (&req.n, sizeof (req), NDA_LLADDR, mac, 6);
req.ndm.ndm_ifindex = ifp->ifindex;
@@ -1944,11 +1952,12 @@ netlink_macfdb_update (struct interface *ifp, vlanid_t vid,
addattr32 (&req.n, sizeof (req), NDA_MASTER, br_if->ifindex);
if (IS_ZEBRA_DEBUG_KERNEL)
- zlog_debug ("Tx %s family %s IF %s(%u)%s MAC %s%s",
+ zlog_debug ("Tx %s family %s IF %s(%u)%s %sMAC %s%s",
nl_msg_type_to_str (cmd),
nl_family_to_str (req.ndm.ndm_family),
ifp->name, ifp->ifindex,
vid_present ? vid_buf : "",
+ sticky ? "sticky " : "",
prefix_mac2str (mac, buf, sizeof (buf)),
dst_present ? dst_buf : "");
@@ -2243,16 +2252,17 @@ netlink_neigh_update2 (struct interface *ifp, struct ipaddr *ip,
int
kernel_add_mac (struct interface *ifp, vlanid_t vid,
- struct ethaddr *mac, struct in_addr vtep_ip)
+ struct ethaddr *mac, struct in_addr vtep_ip,
+ u_char sticky)
{
- return netlink_macfdb_update (ifp, vid, mac, vtep_ip, 0, RTM_NEWNEIGH);
+ return netlink_macfdb_update (ifp, vid, mac, vtep_ip, 0, RTM_NEWNEIGH, sticky);
}
int
kernel_del_mac (struct interface *ifp, vlanid_t vid,
struct ethaddr *mac, struct in_addr vtep_ip, int local)
{
- return netlink_macfdb_update (ifp, vid, mac, vtep_ip, local, RTM_DELNEIGH);
+ return netlink_macfdb_update (ifp, vid, mac, vtep_ip, local, RTM_DELNEIGH, 0);
}
int kernel_add_neigh (struct interface *ifp, struct ipaddr *ip,