diff options
Diffstat (limited to 'zebra/rt_netlink.c')
| -rw-r--r-- | zebra/rt_netlink.c | 110 |
1 files changed, 65 insertions, 45 deletions
diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index f59fbae3af..1cae0b1f9b 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -77,16 +77,7 @@ /* Re-defining as I am unable to include <linux/if_bridge.h> which has the * UAPI for MAC sync. */ #ifndef _UAPI_LINUX_IF_BRIDGE_H -/* FDB notification bits for NDA_NOTIFY: - * - BR_FDB_NFY_STATIC - notify on activity/expire even for a static entry - * - BR_FDB_NFY_INACTIVE - mark as inactive to avoid double notification, - * used with BR_FDB_NFY_STATIC (kernel controlled) - */ -enum { - BR_FDB_NFY_STATIC, - BR_FDB_NFY_INACTIVE, - BR_FDB_NFY_MAX -}; +#define BR_SPH_LIST_SIZE 10 #endif static vlanid_t filter_vlan = 0; @@ -266,6 +257,10 @@ static inline int zebra2proto(int proto) case ZEBRA_ROUTE_NHG: proto = RTPROT_ZEBRA; break; + case ZEBRA_ROUTE_CONNECT: + case ZEBRA_ROUTE_KERNEL: + proto = RTPROT_KERNEL; + break; default: /* * When a user adds a new protocol this will show up @@ -869,7 +864,7 @@ static int netlink_route_change_read_unicast(struct nlmsghdr *h, ns_id_t ns_id, if (nhe_id) { rib_delete(afi, SAFI_UNICAST, vrf_id, proto, 0, flags, &p, &src_p, NULL, nhe_id, table, metric, - distance, true, false); + distance, true); } else { if (!tb[RTA_MULTIPATH]) { struct nexthop nh; @@ -879,13 +874,13 @@ static int netlink_route_change_read_unicast(struct nlmsghdr *h, ns_id_t ns_id, gate, afi, vrf_id); rib_delete(afi, SAFI_UNICAST, vrf_id, proto, 0, flags, &p, &src_p, &nh, 0, table, - metric, distance, true, false); + metric, distance, true); } else { /* XXX: need to compare the entire list of * nexthops here for NLM_F_APPEND stupidity */ rib_delete(afi, SAFI_UNICAST, vrf_id, proto, 0, flags, &p, &src_p, NULL, 0, table, - metric, distance, true, false); + metric, distance, true); } } } @@ -2486,13 +2481,6 @@ static int netlink_nexthop_process_group(struct rtattr **tb, return count; } -#if 0 - // TODO: Need type for something? - zlog_debug("Nexthop group type: %d", - *((uint16_t *)RTA_DATA(tb[NHA_GROUP_TYPE]))); - -#endif - for (int i = 0; ((i < count) && (i < z_grp_size)); i++) { z_grp[i].id = n_grp[i].id; z_grp[i].weight = n_grp[i].weight + 1; @@ -2762,11 +2750,23 @@ static ssize_t netlink_neigh_update_msg_encode( } if (nfy) { - if (!nl_attr_put(&req->n, datalen, NDA_NOTIFY, - &nfy_flags, sizeof(nfy_flags))) + struct rtattr *nest; + + nest = nl_attr_nest(&req->n, datalen, + NDA_FDB_EXT_ATTRS | NLA_F_NESTED); + if (!nest) + return 0; + + if (!nl_attr_put(&req->n, datalen, NFEA_ACTIVITY_NOTIFY, + &nfy_flags, sizeof(nfy_flags))) + return 0; + if (!nl_attr_put(&req->n, datalen, NFEA_DONT_REFRESH, NULL, 0)) return 0; + + nl_attr_nest_end(&req->n, nest); } + if (ext) { if (!nl_attr_put(&req->n, datalen, NDA_EXT_FLAGS, &ext_flags, sizeof(ext_flags))) @@ -2851,7 +2851,8 @@ static int netlink_macfdb_change(struct nlmsghdr *h, int len, ns_id_t ns_id) * validation of the fields. */ memset(tb, 0, sizeof tb); - netlink_parse_rtattr(tb, NDA_MAX, NDA_RTA(ndm), len); + netlink_parse_rtattr_flags(tb, NDA_MAX, NDA_RTA(ndm), len, + NLA_F_NESTED); if (!tb[NDA_LLADDR]) { if (IS_ZEBRA_DEBUG_KERNEL) @@ -2893,14 +2894,21 @@ static int netlink_macfdb_change(struct nlmsghdr *h, int len, ns_id_t ns_id) if (ndm->ndm_state & NUD_STALE) local_inactive = true; - if (tb[NDA_NOTIFY]) { - uint8_t nfy_flags; + if (tb[NDA_FDB_EXT_ATTRS]) { + struct rtattr *attr = tb[NDA_FDB_EXT_ATTRS]; + struct rtattr *nfea_tb[NFEA_MAX + 1] = {0}; - dp_static = true; - nfy_flags = *(uint8_t *)RTA_DATA(tb[NDA_NOTIFY]); - /* local activity has not been detected on the entry */ - if (nfy_flags & (1 << BR_FDB_NFY_INACTIVE)) - local_inactive = true; + netlink_parse_rtattr_nested(nfea_tb, NFEA_MAX, attr); + if (nfea_tb[NFEA_ACTIVITY_NOTIFY]) { + uint8_t nfy_flags; + + nfy_flags = *(uint8_t *)RTA_DATA( + nfea_tb[NFEA_ACTIVITY_NOTIFY]); + if (nfy_flags & FDB_NOTIFY_BIT) + dp_static = true; + if (nfy_flags & FDB_NOTIFY_INACTIVE_BIT) + local_inactive = true; + } } if (IS_ZEBRA_DEBUG_KERNEL) @@ -3202,12 +3210,12 @@ ssize_t netlink_macfdb_update_ctx(struct zebra_dplane_ctx *ctx, void *data, } else { /* local mac */ if (update_flags & DPLANE_MAC_SET_STATIC) { - nfy_flags |= (1 << BR_FDB_NFY_STATIC); + nfy_flags |= FDB_NOTIFY_BIT; state |= NUD_NOARP; } if (update_flags & DPLANE_MAC_SET_INACTIVE) - nfy_flags |= (1 << BR_FDB_NFY_INACTIVE); + nfy_flags |= FDB_NOTIFY_INACTIVE_BIT; nfy = true; } @@ -3300,6 +3308,8 @@ static int netlink_ipneigh_change(struct nlmsghdr *h, int len, ns_id_t ns_id) bool is_ext; bool is_router; bool local_inactive; + uint32_t ext_flags = 0; + bool dp_static = false; ndm = NLMSG_DATA(h); @@ -3333,7 +3343,7 @@ static int netlink_ipneigh_change(struct nlmsghdr *h, int len, ns_id_t ns_id) netlink_handle_5549(ndm, zif, ifp, &ip, false); if (IS_ZEBRA_DEBUG_KERNEL) zlog_debug( - "\tNeighbor Entry Received is a 5549 entry, finished"); + " Neighbor Entry Received is a 5549 entry, finished"); return 0; } @@ -3362,7 +3372,7 @@ static int netlink_ipneigh_change(struct nlmsghdr *h, int len, ns_id_t ns_id) else { if (IS_ZEBRA_DEBUG_KERNEL) zlog_debug( - "\tNeighbor Entry received is not on a VLAN or a BRIDGE, ignoring"); + " Neighbor Entry received is not on a VLAN or a BRIDGE, ignoring"); return 0; } @@ -3391,9 +3401,15 @@ static int netlink_ipneigh_change(struct nlmsghdr *h, int len, ns_id_t ns_id) is_ext = !!(ndm->ndm_flags & NTF_EXT_LEARNED); is_router = !!(ndm->ndm_flags & NTF_ROUTER); + if (tb[NDA_EXT_FLAGS]) { + ext_flags = *(uint32_t *)RTA_DATA(tb[NDA_EXT_FLAGS]); + if (ext_flags & NTF_E_MH_PEER_SYNC) + dp_static = true; + } + if (IS_ZEBRA_DEBUG_KERNEL) zlog_debug( - "Rx %s family %s IF %s(%u) vrf %s(%u) IP %s MAC %s state 0x%x flags 0x%x", + "Rx %s family %s IF %s(%u) vrf %s(%u) IP %s MAC %s state 0x%x flags 0x%x ext_flags 0x%x", nl_msg_type_to_str(h->nlmsg_type), nl_family_to_str(ndm->ndm_family), ifp->name, ndm->ndm_ifindex, VRF_LOGNAME(vrf), ifp->vrf_id, @@ -3401,7 +3417,7 @@ static int netlink_ipneigh_change(struct nlmsghdr *h, int len, ns_id_t ns_id) mac_present ? prefix_mac2str(&mac, buf, sizeof(buf)) : "", - ndm->ndm_state, ndm->ndm_flags); + ndm->ndm_state, ndm->ndm_flags, ext_flags); /* If the neighbor state is valid for use, process as an add or * update @@ -3410,15 +3426,19 @@ static int netlink_ipneigh_change(struct nlmsghdr *h, int len, ns_id_t ns_id) * in re-adding the neighbor if it is a valid "remote" neighbor. */ if (ndm->ndm_state & NUD_VALID) { - local_inactive = !(ndm->ndm_state & NUD_LOCAL_ACTIVE); + if (zebra_evpn_mh_do_adv_reachable_neigh_only()) + local_inactive = + !(ndm->ndm_state & NUD_LOCAL_ACTIVE); + else + /* If EVPN-MH is not enabled we treat STALE + * neighbors as locally-active and advertise + * them + */ + local_inactive = false; - /* XXX - populate dp-static based on the sync flags - * in the kernel - */ return zebra_vxlan_handle_kernel_neigh_update( - ifp, link_if, &ip, &mac, ndm->ndm_state, - is_ext, is_router, local_inactive, - false /* dp_static */); + ifp, link_if, &ip, &mac, ndm->ndm_state, is_ext, + is_router, local_inactive, dp_static); } return zebra_vxlan_handle_kernel_neigh_del(ifp, link_if, &ip); @@ -3689,12 +3709,12 @@ static ssize_t netlink_neigh_update_ctx(const struct zebra_dplane_ctx *ctx, char buf2[ETHER_ADDR_STRLEN]; zlog_debug( - "Tx %s family %s IF %s(%u) Neigh %s MAC %s flags 0x%x state 0x%x", + "Tx %s family %s IF %s(%u) Neigh %s MAC %s flags 0x%x state 0x%x %sext_flags 0x%x", nl_msg_type_to_str(cmd), nl_family_to_str(family), dplane_ctx_get_ifname(ctx), dplane_ctx_get_ifindex(ctx), ipaddr2str(ip, buf, sizeof(buf)), mac ? prefix_mac2str(mac, buf2, sizeof(buf2)) : "null", - flags, state); + flags, state, ext ? "ext " : "", ext_flags); } return netlink_neigh_update_msg_encode( |
