diff options
| author | vivek <vivek@cumulusnetworks.com> | 2017-05-15 14:42:57 -0700 |
|---|---|---|
| committer | Donald Sharp <sharpd@cumulusnetworks.com> | 2017-07-12 14:37:14 -0400 |
| commit | c85c03c7f90bfc6110c4621bfb096690c70b8bec (patch) | |
| tree | 0430b6cca5448f0a38ec49d4a735378b112d72d4 /zebra/rt_netlink.c | |
| parent | 128ea8abbd38eddd2a9bfa18b596acd95f081353 (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.c | 26 |
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, |
