From 64e0ac29ddc43bb5b1a2999a8ebedbdff115e3ca Mon Sep 17 00:00:00 2001 From: Paul Jakma Date: Wed, 18 Nov 2015 16:00:54 +0000 Subject: [PATCH] bgpd: Implicit updates in BGP may require a withdrawal from zebra RIB * J Yu noted a problem with bgpd of routes not having their nexthop updated correctly. Martin Winter pinned this down to the case where a BGP route is updated from one with a valid nexthop to an invalid next-hop, using a test tool. Once the problem occurs, the incorrect route may remain, even after further UPDATEs, so long as the nexthop in the zebra RIB does not match the BGP route's nexthop. Jacqueline Yu then pinned the issue down further to being due to bgpd sending the DELETE for the route to zebra with the new nexthop after a BGP UPDATE updates an existing route, but then is found to be invalid, and zebra not finding the route as it requires a match on all attributes. * bgp_zebra.c: (bgp_zebra_withdraw) When deleting a prefix, we want it gone. Do not send additional matching attributes like the nexthop, which can only cause incorrect non-matches. Acked-by: Donald Sharp --- bgpd/bgp_zebra.c | 46 +++++----------------------------------------- 1 file changed, 5 insertions(+), 41 deletions(-) diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index e534bee..186657b 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -863,18 +863,14 @@ bgp_zebra_withdraw (struct prefix *p, struct bgp_info *info, safi_t safi) if (p->family == AF_INET) { struct zapi_ipv4 api; - struct in_addr *nexthop; api.vrf_id = VRF_DEFAULT; api.flags = flags; - nexthop = &info->attr->nexthop; api.type = ZEBRA_ROUTE_BGP; api.message = 0; api.safi = safi; - SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP); - api.nexthop_num = 1; - api.nexthop = &nexthop; + api.nexthop_num = 0; api.ifindex_num = 0; SET_FLAG (api.message, ZAPI_MESSAGE_METRIC); api.metric = info->attr->med; @@ -882,10 +878,9 @@ bgp_zebra_withdraw (struct prefix *p, struct bgp_info *info, safi_t safi) if (BGP_DEBUG(zebra, ZEBRA)) { char buf[2][INET_ADDRSTRLEN]; - zlog_debug("Zebra send: IPv4 route delete %s/%d nexthop %s metric %u", + zlog_debug("Zebra send: IPv4 route delete %s/%d metric %u", inet_ntop(AF_INET, &p->u.prefix4, buf[0], sizeof(buf[0])), p->prefixlen, - inet_ntop(AF_INET, nexthop, buf[1], sizeof(buf[1])), api.metric); } @@ -897,54 +892,23 @@ bgp_zebra_withdraw (struct prefix *p, struct bgp_info *info, safi_t safi) if (p->family == AF_INET6) { struct zapi_ipv6 api; - unsigned int ifindex; - struct in6_addr *nexthop; - - assert (info->attr->extra); - ifindex = 0; - nexthop = NULL; - - /* Only global address nexthop exists. */ - if (info->attr->extra->mp_nexthop_len == 16) - nexthop = &info->attr->extra->mp_nexthop_global; - - /* If both global and link-local address present. */ - if (info->attr->extra->mp_nexthop_len == 32) - { - nexthop = &info->attr->extra->mp_nexthop_local; - if (info->peer->nexthop.ifp) - ifindex = info->peer->nexthop.ifp->ifindex; - } - - if (nexthop == NULL) - return; - - if (IN6_IS_ADDR_LINKLOCAL (nexthop) && ! ifindex) - if (info->peer->ifname) - ifindex = ifname2ifindex (info->peer->ifname); - api.vrf_id = VRF_DEFAULT; api.flags = flags; api.type = ZEBRA_ROUTE_BGP; api.message = 0; api.safi = safi; - SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP); - api.nexthop_num = 1; - api.nexthop = &nexthop; - SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX); - api.ifindex_num = 1; - api.ifindex = &ifindex; + api.nexthop_num = 0; + api.ifindex_num = 0; SET_FLAG (api.message, ZAPI_MESSAGE_METRIC); api.metric = info->attr->med; if (BGP_DEBUG(zebra, ZEBRA)) { char buf[2][INET6_ADDRSTRLEN]; - zlog_debug("Zebra send: IPv6 route delete %s/%d nexthop %s metric %u", + zlog_debug("Zebra send: IPv6 route delete %s/%d metric %u", inet_ntop(AF_INET6, &p->u.prefix6, buf[0], sizeof(buf[0])), p->prefixlen, - inet_ntop(AF_INET6, nexthop, buf[1], sizeof(buf[1])), api.metric); } -- 2.7.0