diff options
Diffstat (limited to 'zebra/rt_netlink.c')
| -rw-r--r-- | zebra/rt_netlink.c | 94 |
1 files changed, 56 insertions, 38 deletions
diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index 3053c56d1e..df53a06bc2 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -397,14 +397,14 @@ static int netlink_route_change_read_unicast(struct sockaddr_nl *snl, if (IS_ZEBRA_DEBUG_KERNEL) { char buf[PREFIX_STRLEN]; char buf2[PREFIX_STRLEN]; - zlog_debug("%s %s%s%s vrf %u metric: %d Admin Distance: %d", + zlog_debug("%s %s%s%s vrf %u(%u) metric: %d Admin Distance: %d", nl_msg_type_to_str(h->nlmsg_type), prefix2str(&p, buf, sizeof(buf)), src_p.prefixlen ? " from " : "", src_p.prefixlen ? prefix2str(&src_p, buf2, sizeof(buf2)) : "", - vrf_id, metric, distance); + vrf_id, table, metric, distance); } afi_t afi = AFI_IP; @@ -1253,23 +1253,21 @@ _netlink_mpls_build_multipath(const char *routedesc, zebra_nhlfe_t *nhlfe, * * @param cmd: Netlink command which is to be processed * @param p: Prefix for which the change is due - * @param nexthop: Nexthop which is currently processed - * @param routedesc: Semantic annotation for nexthop - * (recursive, multipath, etc.) * @param family: Address family which the change concerns + * @param zvrf: The vrf we are in + * @param tableid: The table we are working on */ static void _netlink_route_debug(int cmd, struct prefix *p, - struct nexthop *nexthop, const char *routedesc, int family, struct zebra_vrf *zvrf, uint32_t tableid) { if (IS_ZEBRA_DEBUG_KERNEL) { char buf[PREFIX_STRLEN]; zlog_debug( - "netlink_route_multipath() (%s): %s %s vrf %u(%u) type %s", - routedesc, nl_msg_type_to_str(cmd), - prefix2str(p, buf, sizeof(buf)), zvrf_id(zvrf), tableid, - (nexthop) ? nexthop_type_to_str(nexthop->type) : "UNK"); + "netlink_route_multipath(): %s %s vrf %u(%u)", + nl_msg_type_to_str(cmd), + prefix2str(p, buf, sizeof(buf)), + zvrf_id(zvrf), tableid); } } @@ -1321,7 +1319,6 @@ static int netlink_route_multipath(int cmd, struct prefix *p, struct sockaddr_nl snl; struct nexthop *nexthop = NULL; unsigned int nexthop_num; - int discard = 0; int family = PREFIX_FAMILY(p); const char *routedesc; int setsrc = 0; @@ -1380,7 +1377,15 @@ static int netlink_route_multipath(int cmd, struct prefix *p, addattr32(&req.n, sizeof req, RTA_TABLE, re->table); } - if (discard) + _netlink_route_debug(cmd, p, family, zvrf, re->table); + + /* + * If we are not updating the route and we have received + * a route delete, then all we need to fill in is the + * prefix information to tell the kernel to schwack + * it. + */ + if (!update && cmd == RTM_DELROUTE) goto skip; if (re->mtu || re->nexthop_mtu) { @@ -1486,8 +1491,6 @@ static int netlink_route_multipath(int cmd, struct prefix *p, ? "recursive, single-path" : "single-path"; - _netlink_route_debug(cmd, p, nexthop, routedesc, - family, zvrf, re->table); _netlink_route_build_singlepath( routedesc, bytelen, nexthop, &req.n, &req.r, sizeof req, cmd); @@ -1570,8 +1573,6 @@ static int netlink_route_multipath(int cmd, struct prefix *p, : "multipath"; nexthop_num++; - _netlink_route_debug(cmd, p, nexthop, routedesc, - family, zvrf, re->table); _netlink_route_build_multipath( routedesc, bytelen, nexthop, rta, rtnh, &req.r, &src1); @@ -2112,21 +2113,53 @@ static int netlink_ipneigh_change(struct sockaddr_nl *snl, struct nlmsghdr *h, ndm = NLMSG_DATA(h); - /* We only process neigh notifications if EVPN is enabled */ - 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) return 0; - /* Drop "permanent" entries. */ - if (ndm->ndm_state & NUD_PERMANENT) + zif = (struct zebra_if *)ifp->info; + + /* Parse attributes and extract fields of interest. */ + memset(tb, 0, sizeof tb); + netlink_parse_rtattr(tb, NDA_MAX, NDA_RTA(ndm), len); + + if (!tb[NDA_DST]) { + zlog_warn("%s family %s IF %s(%u) - no DST", + nl_msg_type_to_str(h->nlmsg_type), + nl_family_to_str(ndm->ndm_family), ifp->name, + ndm->ndm_ifindex); return 0; + } + + memset(&ip, 0, sizeof(struct ipaddr)); + ip.ipa_type = (ndm->ndm_family == AF_INET) ? IPADDR_V4 : IPADDR_V6; + memcpy(&ip.ip.addr, RTA_DATA(tb[NDA_DST]), RTA_PAYLOAD(tb[NDA_DST])); + + /* Drop some "permanent" entries. */ + if (ndm->ndm_state & NUD_PERMANENT) { + char buf[16] = "169.254.0.1"; + struct in_addr ipv4_ll; + + if (ndm->ndm_family != AF_INET) + return 0; + + if (!zif->v6_2_v4_ll_neigh_entry) + return 0; + + if (h->nlmsg_type != RTM_DELNEIGH) + return 0; + + inet_pton(AF_INET, buf, &ipv4_ll); + if (ipv4_ll.s_addr != ip.ip._v4_addr.s_addr) + return 0; + + if_nbr_ipv6ll_to_ipv4ll_neigh_update( + ifp, &zif->v6_2_v4_ll_addr6, true); + return 0; + } - zif = (struct zebra_if *)ifp->info; /* 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. @@ -2148,22 +2181,7 @@ static int netlink_ipneigh_change(struct sockaddr_nl *snl, struct nlmsghdr *h, else return 0; - /* Parse attributes and extract fields of interest. */ - memset(tb, 0, sizeof tb); - netlink_parse_rtattr(tb, NDA_MAX, NDA_RTA(ndm), len); - - if (!tb[NDA_DST]) { - zlog_warn("%s family %s IF %s(%u) - no DST", - nl_msg_type_to_str(h->nlmsg_type), - nl_family_to_str(ndm->ndm_family), ifp->name, - ndm->ndm_ifindex); - return 0; - } memset(&mac, 0, sizeof(struct ethaddr)); - memset(&ip, 0, sizeof(struct ipaddr)); - ip.ipa_type = (ndm->ndm_family == AF_INET) ? IPADDR_V4 : IPADDR_V6; - memcpy(&ip.ip.addr, RTA_DATA(tb[NDA_DST]), RTA_PAYLOAD(tb[NDA_DST])); - if (h->nlmsg_type == RTM_NEWNEIGH) { if (tb[NDA_LLADDR]) { if (RTA_PAYLOAD(tb[NDA_LLADDR]) != ETH_ALEN) { |
