diff options
Diffstat (limited to 'zebra/rt_netlink.c')
| -rw-r--r-- | zebra/rt_netlink.c | 137 |
1 files changed, 68 insertions, 69 deletions
diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index 7011342ab4..e40bf45f59 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -142,7 +142,7 @@ static uint16_t neigh_state_to_netlink(uint16_t dplane_state) } -static inline int is_selfroute(int proto) +static inline bool is_selfroute(int proto) { if ((proto == RTPROT_BGP) || (proto == RTPROT_OSPF) || (proto == RTPROT_ZSTATIC) || (proto == RTPROT_ZEBRA) @@ -151,10 +151,10 @@ static inline int is_selfroute(int proto) || (proto == RTPROT_LDP) || (proto == RTPROT_BABEL) || (proto == RTPROT_RIP) || (proto == RTPROT_SHARP) || (proto == RTPROT_PBR) || (proto == RTPROT_OPENFABRIC)) { - return 1; + return true; } - return 0; + return false; } static inline int zebra2proto(int proto) @@ -513,6 +513,7 @@ static int netlink_route_change_read_unicast(struct nlmsghdr *h, ns_id_t ns_id, struct prefix p; struct prefix_ipv6 src_p = {}; vrf_id_t vrf_id; + bool selfroute; char anyaddr[16] = {0}; @@ -574,8 +575,9 @@ static int netlink_route_change_read_unicast(struct nlmsghdr *h, ns_id_t ns_id, if (rtm->rtm_protocol == RTPROT_KERNEL) return 0; - if (!startup && is_selfroute(rtm->rtm_protocol) - && h->nlmsg_type == RTM_NEWROUTE) { + selfroute = is_selfroute(rtm->rtm_protocol); + + if (!startup && selfroute && h->nlmsg_type == RTM_NEWROUTE) { if (IS_ZEBRA_DEBUG_KERNEL) zlog_debug("Route type: %d Received that we think we have originated, ignoring", rtm->rtm_protocol); @@ -602,7 +604,7 @@ static int netlink_route_change_read_unicast(struct nlmsghdr *h, ns_id_t ns_id, } /* Route which inserted by Zebra. */ - if (is_selfroute(rtm->rtm_protocol)) { + if (selfroute) { flags |= ZEBRA_FLAG_SELFROUTE; proto = proto2zebra(rtm->rtm_protocol, rtm->rtm_family, false); } @@ -2588,7 +2590,7 @@ static int netlink_macfdb_change(struct nlmsghdr *h, int len, ns_id_t ns_id) struct interface *br_if; struct ethaddr mac; vlanid_t vid = 0; - struct prefix vtep_ip; + struct in_addr vtep_ip; int vid_present = 0, dst_present = 0; char buf[ETHER_ADDR_STRLEN]; char vid_buf[20]; @@ -2601,66 +2603,25 @@ static int netlink_macfdb_change(struct nlmsghdr *h, int len, ns_id_t ns_id) if (!is_evpn_enabled()) return 0; - /* The interface should exist. */ - ifp = if_lookup_by_index_per_ns(zebra_ns_lookup(ns_id), - ndm->ndm_ifindex); - if (!ifp || !ifp->info) { - if (IS_ZEBRA_DEBUG_KERNEL) - zlog_debug("\t%s without associated interface: %u", - __func__, ndm->ndm_ifindex); - return 0; - } - - /* The interface should be something we're interested in. */ - if (!IS_ZEBRA_IF_BRIDGE_SLAVE(ifp)) { - if (IS_ZEBRA_DEBUG_KERNEL) - zlog_debug("\t%s Not interested in %s, not a slave", - __func__, ifp->name); - return 0; - } - - /* Drop "permanent" entries. */ - if (ndm->ndm_state & NUD_PERMANENT) { - if (IS_ZEBRA_DEBUG_KERNEL) - zlog_debug("\t%s Entry is PERMANENT, dropping", - __func__); - return 0; - } - - zif = (struct zebra_if *)ifp->info; - if ((br_if = zif->brslave_info.br_if) == NULL) { - if (IS_ZEBRA_DEBUG_KERNEL) - zlog_debug( - "%s family %s IF %s(%u) brIF %u - no bridge master", - nl_msg_type_to_str(h->nlmsg_type), - nl_family_to_str(ndm->ndm_family), ifp->name, - ndm->ndm_ifindex, - zif->brslave_info.bridge_ifindex); - return 0; - } - - /* Parse attributes and extract fields of interest. */ - memset(tb, 0, sizeof(tb)); + /* Parse attributes and extract fields of interest. Do basic + * validation of the fields. + */ + memset(tb, 0, sizeof tb); netlink_parse_rtattr(tb, NDA_MAX, NDA_RTA(ndm), len); if (!tb[NDA_LLADDR]) { if (IS_ZEBRA_DEBUG_KERNEL) - zlog_debug("%s family %s IF %s(%u) brIF %u - no LLADDR", + zlog_debug("%s AF_BRIDGE IF %u - no LLADDR", nl_msg_type_to_str(h->nlmsg_type), - nl_family_to_str(ndm->ndm_family), ifp->name, - ndm->ndm_ifindex, - zif->brslave_info.bridge_ifindex); + ndm->ndm_ifindex); return 0; } if (RTA_PAYLOAD(tb[NDA_LLADDR]) != ETH_ALEN) { if (IS_ZEBRA_DEBUG_KERNEL) zlog_debug( - "%s family %s IF %s(%u) brIF %u - LLADDR is not MAC, len %lu", - nl_msg_type_to_str(h->nlmsg_type), - nl_family_to_str(ndm->ndm_family), ifp->name, - ndm->ndm_ifindex, - zif->brslave_info.bridge_ifindex, + "%s AF_BRIDGE IF %u - LLADDR is not MAC, len %lu", + nl_msg_type_to_str(h->nlmsg_type), ndm->ndm_ifindex, (unsigned long)RTA_PAYLOAD(tb[NDA_LLADDR])); return 0; } @@ -2676,24 +2637,42 @@ static int netlink_macfdb_change(struct nlmsghdr *h, int len, ns_id_t ns_id) if (tb[NDA_DST]) { /* TODO: Only IPv4 supported now. */ dst_present = 1; - vtep_ip.family = AF_INET; - vtep_ip.prefixlen = IPV4_MAX_BITLEN; - memcpy(&(vtep_ip.u.prefix4.s_addr), RTA_DATA(tb[NDA_DST]), + memcpy(&vtep_ip.s_addr, RTA_DATA(tb[NDA_DST]), IPV4_MAX_BYTELEN); - sprintf(dst_buf, " dst %s", inet_ntoa(vtep_ip.u.prefix4)); + sprintf(dst_buf, " dst %s", inet_ntoa(vtep_ip)); } - sticky = !!(ndm->ndm_state & NUD_NOARP); - if (IS_ZEBRA_DEBUG_KERNEL) - zlog_debug("Rx %s family %s IF %s(%u)%s %sMAC %s%s", + zlog_debug("Rx %s AF_BRIDGE IF %u%s st 0x%x fl 0x%x MAC %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 " : "", + ndm->ndm_state, ndm->ndm_flags, prefix_mac2str(&mac, buf, sizeof(buf)), dst_present ? dst_buf : ""); + /* The interface should exist. */ + ifp = if_lookup_by_index_per_ns(zebra_ns_lookup(ns_id), + ndm->ndm_ifindex); + if (!ifp || !ifp->info) + return 0; + + /* The interface should be something we're interested in. */ + if (!IS_ZEBRA_IF_BRIDGE_SLAVE(ifp)) + return 0; + + zif = (struct zebra_if *)ifp->info; + if ((br_if = zif->brslave_info.br_if) == NULL) { + if (IS_ZEBRA_DEBUG_KERNEL) + zlog_debug( + "%s AF_BRIDGE IF %s(%u) brIF %u - no bridge master", + nl_msg_type_to_str(h->nlmsg_type), ifp->name, + ndm->ndm_ifindex, + zif->brslave_info.bridge_ifindex); + return 0; + } + + sticky = !!(ndm->ndm_state & NUD_NOARP); + if (filter_vlan && vid != filter_vlan) { if (IS_ZEBRA_DEBUG_KERNEL) zlog_debug("\tFiltered due to filter vlan: %d", @@ -2707,6 +2686,13 @@ static int netlink_macfdb_change(struct nlmsghdr *h, int len, ns_id_t ns_id) * so perform an implicit delete of any local entry (if it exists). */ if (h->nlmsg_type == RTM_NEWNEIGH) { + /* Drop "permanent" entries. */ + if (ndm->ndm_state & NUD_PERMANENT) { + if (IS_ZEBRA_DEBUG_KERNEL) + zlog_debug("\tDropping entry because of NUD_PERMANENT"); + return 0; + } + if (IS_ZEBRA_IF_VXLAN(ifp)) return zebra_vxlan_check_del_local_mac(ifp, br_if, &mac, vid); @@ -2716,16 +2702,20 @@ static int netlink_macfdb_change(struct nlmsghdr *h, int len, ns_id_t ns_id) } /* This is a delete notification. + * Ignore the notification with IP dest as it may just signify that the + * MAC has moved from remote to local. The exception is the special + * all-zeros MAC that represents the BUM flooding entry; we may have + * to readd it. Otherwise, * 1. For a MAC over VxLan, check if it needs to be refreshed(readded) * 2. For a MAC over "local" interface, delete the mac * Note: We will get notifications from both bridge driver and VxLAN * driver. - * Ignore the notification from VxLan driver as it is also generated - * when mac moves from remote to local. */ if (dst_present) { - if (IS_ZEBRA_DEBUG_KERNEL) - zlog_debug("\tNo Destination Present"); + u_char zero_mac[6] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; + + if (!memcmp(zero_mac, mac.octet, ETH_ALEN)) + return zebra_vxlan_check_readd_vtep(ifp, vtep_ip); return 0; } @@ -3285,6 +3275,15 @@ static int netlink_request_specific_neigh_in_vlan(struct zebra_ns *zns, addattr_l(&req.n, sizeof(req), NDA_DST, &ip->ip.addr, ipa_len); + if (IS_ZEBRA_DEBUG_KERNEL) { + char buf[INET6_ADDRSTRLEN]; + + zlog_debug("%s: Tx %s family %s IF %u IP %s flags 0x%x", + __func__, nl_msg_type_to_str(type), + nl_family_to_str(req.ndm.ndm_family), ifindex, + ipaddr2str(ip, buf, sizeof(buf)), req.n.nlmsg_flags); + } + return netlink_request(&zns->netlink_cmd, &req.n); } |
