From 9de1f7ff13889391e72162a50619b2ff275209f4 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Wed, 15 Nov 2017 13:22:56 -0500 Subject: [PATCH] bgpd: Allow bgp to understand the different nexthop types When BGP is being redistributed prefixes, allow it to understand the nexthop type. This fixes the issue where a blackhole route was being interpreted to having a nexthop of 1.0.0.0( ruh-roh!!! ). This broke downstream neighbors as that they would receive a 1.0.0.0 nexthop, which is bad, very very bad. This commit sets us up for the future where we can match a route-map against a nexthop type. In that bgp is now at least nominally paying attention to the type. Signed-off-by: Donald Sharp --- bgpd/bgp_route.c | 27 ++++++++++++++++++++++----- bgpd/bgp_route.h | 8 +++++--- bgpd/bgp_zebra.c | 8 +++++--- 3 files changed, 32 insertions(+), 11 deletions(-) diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 4ee1aafbe9..e0ae2a9611 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -6148,8 +6148,9 @@ DEFUN (no_ipv6_aggregate_address, /* Redistribute route treatment. */ void bgp_redistribute_add(struct bgp *bgp, struct prefix *p, - const union g_addr *nexthop, unsigned int ifindex, - u_int32_t metric, u_char type, u_short instance, + const union g_addr *nexthop, ifindex_t ifindex, + enum nexthop_types_t nhtype, uint32_t metric, + u_char type, u_short instance, route_tag_t tag) { struct bgp_info *new; @@ -6164,15 +6165,31 @@ void bgp_redistribute_add(struct bgp *bgp, struct prefix *p, /* Make default attribute. */ bgp_attr_default_set(&attr, BGP_ORIGIN_INCOMPLETE); - if (nexthop) { + + switch(nhtype) { + case NEXTHOP_TYPE_IFINDEX: + break; + case NEXTHOP_TYPE_IPV4: + case NEXTHOP_TYPE_IPV4_IFINDEX: + attr.nexthop = nexthop->ipv4; + break; + case NEXTHOP_TYPE_IPV6: + case NEXTHOP_TYPE_IPV6_IFINDEX: + attr.mp_nexthop_global = nexthop->ipv6; + attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL; + break; + case NEXTHOP_TYPE_BLACKHOLE: switch (p->family) { case AF_INET: - attr.nexthop = nexthop->ipv4; + attr.nexthop.s_addr = INADDR_ANY; break; case AF_INET6: - attr.mp_nexthop_global = nexthop->ipv6; + memset(&attr.mp_nexthop_global, 0, + sizeof(attr.mp_nexthop_global)); attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL; + break; } + break; } attr.nh_ifindex = ifindex; diff --git a/bgpd/bgp_route.h b/bgpd/bgp_route.h index 6fbeed8963..085de3fabb 100644 --- a/bgpd/bgp_route.h +++ b/bgpd/bgp_route.h @@ -328,9 +328,11 @@ extern int bgp_nlri_parse_ip(struct peer *, struct attr *, struct bgp_nlri *); extern int bgp_maximum_prefix_overflow(struct peer *, afi_t, safi_t, int); -extern void bgp_redistribute_add(struct bgp *, struct prefix *, - const union g_addr *, unsigned int ifindex, - u_int32_t, u_char, u_short, route_tag_t); +extern void bgp_redistribute_add(struct bgp *bgp, struct prefix *p, + const union g_addr *nexthop, ifindex_t ifindex, + enum nexthop_types_t nhtype, uint32_t metric, + u_char type, u_short instance, + route_tag_t tag); extern void bgp_redistribute_delete(struct bgp *, struct prefix *, u_char, u_short); extern void bgp_redistribute_withdraw(struct bgp *, afi_t, int, u_short); diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index bec7050226..b6bf008bae 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -524,9 +524,10 @@ static int bgp_interface_vrf_update(int command, struct zclient *zclient, static int zebra_read_route(int command, struct zclient *zclient, zebra_size_t length, vrf_id_t vrf_id) { + enum nexthop_types_t nhtype; struct zapi_route api; union g_addr nexthop; - unsigned int ifindex; + ifindex_t ifindex; int add, i; struct bgp *bgp; @@ -548,6 +549,7 @@ static int zebra_read_route(int command, struct zclient *zclient, nexthop = api.nexthops[0].gate; ifindex = api.nexthops[0].ifindex; + nhtype = api.nexthops[0].type; add = (command == ZEBRA_REDISTRIBUTE_ROUTE_ADD); if (add) { @@ -568,8 +570,8 @@ static int zebra_read_route(int command, struct zclient *zclient, /* Now perform the add/update. */ bgp_redistribute_add(bgp, &api.prefix, &nexthop, ifindex, - api.metric, api.type, api.instance, - api.tag); + nhtype, api.metric, api.type, + api.instance, api.tag); } else { bgp_redistribute_delete(bgp, &api.prefix, api.type, api.instance); -- 2.39.5