mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-02 18:52:04 +00:00
Merge pull request #1157 from donaldsharp/recursive_blackhole
Recursive blackhole resolution
This commit is contained in:
commit
b1cebe20cd
@ -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,
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user