Merge pull request #1157 from donaldsharp/recursive_blackhole

Recursive blackhole resolution
This commit is contained in:
Jafar Al-Gharaibeh 2017-09-21 11:16:35 -05:00 committed by GitHub
commit b1cebe20cd
3 changed files with 80 additions and 86 deletions

View File

@ -430,12 +430,59 @@ int bgp_multiaccess_check_v4(struct in_addr nexthop, struct peer *peer)
return (ret);
}
static void bgp_show_nexthops_detail(struct vty *vty,
struct bgp *bgp,
struct bgp_nexthop_cache *bnc)
{
char buf[PREFIX2STR_BUFFER];
struct nexthop *nexthop;
for (nexthop = bnc->nexthop; nexthop; nexthop = nexthop->next)
switch (nexthop->type) {
case NEXTHOP_TYPE_IPV6:
vty_out(vty, " gate %s\n",
inet_ntop(AF_INET6, &nexthop->gate.ipv6,
buf, sizeof(buf)));
break;
case NEXTHOP_TYPE_IPV6_IFINDEX:
vty_out(vty, " gate %s, if %s\n",
inet_ntop(AF_INET6, &nexthop->gate.ipv6,
buf, sizeof(buf)),
ifindex2ifname(nexthop->ifindex,
bgp->vrf_id));
break;
case NEXTHOP_TYPE_IPV4:
vty_out(vty, " gate %s\n",
inet_ntop(AF_INET, &nexthop->gate.ipv4,
buf, sizeof(buf)));
break;
case NEXTHOP_TYPE_IFINDEX:
vty_out(vty, " if %s\n",
ifindex2ifname(nexthop->ifindex,
bgp->vrf_id));
break;
case NEXTHOP_TYPE_IPV4_IFINDEX:
vty_out(vty, " gate %s, if %s\n",
inet_ntop(AF_INET, &nexthop->gate.ipv4,
buf, sizeof(buf)),
ifindex2ifname(nexthop->ifindex,
bgp->vrf_id));
break;
case NEXTHOP_TYPE_BLACKHOLE:
vty_out(vty, " blackhole\n");
break;
default:
vty_out(vty,
" invalid nexthop type %u\n",
nexthop->type);
}
}
static void bgp_show_nexthops(struct vty *vty, struct bgp *bgp, int detail)
{
struct bgp_node *rn;
struct bgp_nexthop_cache *bnc;
char buf[PREFIX2STR_BUFFER];
struct nexthop *nexthop;
time_t tbuf;
afi_t afi;
@ -454,70 +501,13 @@ static void bgp_show_nexthops(struct vty *vty, struct bgp *bgp, int detail)
&rn->p.u.prefix, buf,
sizeof(buf)),
bnc->metric, bnc->path_count);
if (detail)
for (nexthop = bnc->nexthop;
nexthop;
nexthop = nexthop->next)
switch (nexthop->type) {
case NEXTHOP_TYPE_IPV6:
vty_out(vty,
" gate %s\n",
inet_ntop(
AF_INET6,
&nexthop->gate
.ipv6,
buf,
sizeof(buf)));
break;
case NEXTHOP_TYPE_IPV6_IFINDEX:
vty_out(vty,
" gate %s, if %s\n",
inet_ntop(
AF_INET6,
&nexthop->gate
.ipv6,
buf,
sizeof(buf)),
ifindex2ifname(
nexthop->ifindex,
bgp->vrf_id));
break;
case NEXTHOP_TYPE_IPV4:
vty_out(vty,
" gate %s\n",
inet_ntop(
AF_INET,
&nexthop->gate
.ipv4,
buf,
sizeof(buf)));
break;
case NEXTHOP_TYPE_IFINDEX:
vty_out(vty,
" if %s\n",
ifindex2ifname(
nexthop->ifindex,
bgp->vrf_id));
break;
case NEXTHOP_TYPE_IPV4_IFINDEX:
vty_out(vty,
" gate %s, if %s\n",
inet_ntop(
AF_INET,
&nexthop->gate
.ipv4,
buf,
sizeof(buf)),
ifindex2ifname(
nexthop->ifindex,
bgp->vrf_id));
break;
default:
vty_out(vty,
" invalid nexthop type %u\n",
nexthop->type);
}
} else {
if (!detail)
continue;
bgp_show_nexthops_detail(vty, bgp, bnc);
} else{
vty_out(vty, " %s invalid\n",
inet_ntop(rn->p.family,
&rn->p.u.prefix, buf,

View File

@ -1320,23 +1320,6 @@ static int netlink_route_multipath(int cmd, struct prefix *p,
req.r.rtm_scope = RT_SCOPE_UNIVERSE;
req.r.rtm_type = RTN_UNICAST;
if (re->nexthop_num == 1
&& re->nexthop->type == NEXTHOP_TYPE_BLACKHOLE) {
discard = 1;
switch (re->nexthop->bh_type) {
case BLACKHOLE_ADMINPROHIB:
req.r.rtm_type = RTN_PROHIBIT;
break;
case BLACKHOLE_REJECT:
req.r.rtm_type = RTN_UNREACHABLE;
break;
default:
req.r.rtm_type = RTN_BLACKHOLE;
break;
}
}
addattr_l(&req.n, sizeof req, RTA_DST, &p->u.prefix, bytelen);
if (src_p)
addattr_l(&req.n, sizeof req, RTA_SRC, &src_p->u.prefix,
@ -1395,6 +1378,27 @@ static int netlink_route_multipath(int cmd, struct prefix *p,
if (nexthop_num == 1 || multipath_num == 1) {
nexthop_num = 0;
for (ALL_NEXTHOPS(re->nexthop, nexthop)) {
/*
* So we want to cover 2 types of blackhole
* routes here:
* 1) A normal blackhole route( ala from a static
* install.
* 2) A recursively resolved blackhole route
*/
if (nexthop->type == NEXTHOP_TYPE_BLACKHOLE) {
switch (nexthop->bh_type) {
case BLACKHOLE_ADMINPROHIB:
req.r.rtm_type = RTN_PROHIBIT;
break;
case BLACKHOLE_REJECT:
req.r.rtm_type = RTN_UNREACHABLE;
break;
default:
req.r.rtm_type = RTN_BLACKHOLE;
break;
}
goto skip;
}
if (CHECK_FLAG(nexthop->flags,
NEXTHOP_FLAG_RECURSIVE)) {
if (!setsrc) {

View File

@ -370,6 +370,10 @@ static void nexthop_set_resolved(afi_t afi, struct nexthop *newhop,
resolved_hop->ifindex = newhop->ifindex;
}
if (newhop->type == NEXTHOP_TYPE_BLACKHOLE) {
resolved_hop->type = NEXTHOP_TYPE_BLACKHOLE;
resolved_hop->bh_type = nexthop->bh_type;
}
resolved_hop->rparent = nexthop;
nexthop_add(&nexthop->resolved, resolved_hop);
}
@ -496,8 +500,6 @@ static int nexthop_active(afi_t afi, struct route_entry *re,
} else if (CHECK_FLAG(re->flags, ZEBRA_FLAG_INTERNAL)) {
resolved = 0;
for (ALL_NEXTHOPS(match->nexthop, newhop)) {
if (newhop->type == NEXTHOP_TYPE_BLACKHOLE)
continue;
if (!CHECK_FLAG(newhop->flags,
NEXTHOP_FLAG_FIB))
continue;
@ -521,8 +523,6 @@ static int nexthop_active(afi_t afi, struct route_entry *re,
} else if (re->type == ZEBRA_ROUTE_STATIC) {
resolved = 0;
for (ALL_NEXTHOPS(match->nexthop, newhop)) {
if (newhop->type == NEXTHOP_TYPE_BLACKHOLE)
continue;
if (!CHECK_FLAG(newhop->flags,
NEXTHOP_FLAG_FIB))
continue;