zebra: cleanup blackhole support

blackhole support was horribly broken. cleanup by removing blackhole
stuff from ZEBRA_FLAG_*

introduces support for "prohibit" routes (Linux/netlink only)
also clean up blackhole options on "ip route" vty commands.

Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
This commit is contained in:
David Lamparter 2010-02-05 04:31:56 +01:00 committed by David Lamparter
parent fd36be7e15
commit a830942228
14 changed files with 213 additions and 218 deletions

View file

@ -76,7 +76,10 @@ struct nexthop {
#define NEXTHOP_FLAG_FILTERED (1 << 5) /* rmap filtered, used by static only */
/* Nexthop address */
union g_addr gate;
union {
union g_addr gate;
enum blackhole_type bh_type;
};
union g_addr src;
union g_addr rmap_src; /* Src is set via routemap */

View file

@ -404,13 +404,13 @@ extern const char *zserv_command_string(unsigned int command);
/* Zebra message flags */
#define ZEBRA_FLAG_INTERNAL 0x01
#define ZEBRA_FLAG_SELFROUTE 0x02
#define ZEBRA_FLAG_BLACKHOLE 0x04
#define ZEBRA_FLAG_IBGP 0x08
#define ZEBRA_FLAG_SELECTED 0x10
#define ZEBRA_FLAG_STATIC 0x40
#define ZEBRA_FLAG_REJECT 0x80
#define ZEBRA_FLAG_SCOPE_LINK 0x100
#define ZEBRA_FLAG_FIB_OVERRIDE 0x200
/* ZEBRA_FLAG_BLACKHOLE was 0x04 */
/* ZEBRA_FLAG_REJECT was 0x80 */
/* Zebra FEC flags. */
#define ZEBRA_FEC_REGISTER_LABEL_INDEX 0x1

View file

@ -887,11 +887,15 @@ void rtm_read(struct rt_msghdr *rtm)
if (flags & RTF_STATIC)
SET_FLAG(zebra_flags, ZEBRA_FLAG_STATIC);
memset(&nh, 0, sizeof(nh));
/* This is a reject or blackhole route */
if (flags & RTF_REJECT)
SET_FLAG(zebra_flags, ZEBRA_FLAG_REJECT);
if (flags & RTF_BLACKHOLE)
SET_FLAG(zebra_flags, ZEBRA_FLAG_BLACKHOLE);
if (flags & RTF_REJECT) {
nh.type = NEXTHOP_TYPE_BLACKHOLE;
nh.bh_type = BLACKHOLE_REJECT;
} else if (flags & RTF_BLACKHOLE) {
nh.type = NEXTHOP_TYPE_BLACKHOLE;
nh.bh_type = BLACKHOLE_NULL;
}
if (dest.sa.sa_family == AF_INET) {
struct prefix p;
@ -1017,11 +1021,12 @@ void rtm_read(struct rt_msghdr *rtm)
if (rtm->rtm_type == RTM_CHANGE)
rib_delete(AFI_IP, SAFI_UNICAST, VRF_DEFAULT,
ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p,
NULL, 0, 0);
NULL, NULL, 0, 0);
memset(&nh, 0, sizeof(nh));
nh.type = NEXTHOP_TYPE_IPV4;
nh.gate.ipv4 = gate.sin;
if (!nh.type) {
nh.type = NEXTHOP_TYPE_IPV4;
nh.gate.ipv4 = gate.sin.sin_addr;
}
if (rtm->rtm_type == RTM_GET || rtm->rtm_type == RTM_ADD
|| rtm->rtm_type == RTM_CHANGE)
@ -1064,11 +1069,12 @@ void rtm_read(struct rt_msghdr *rtm)
ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p,
NULL, NULL, 0, 0);
memset(&nh, 0, sizeof(nh));
nh.type = ifindex ? NEXTHOP_TYPE_IPV6_IFINDEX
: NEXTHOP_TYPE_IPV6;
nh.gate.ipv6 = gate.sin6;
nh.ifindex = ifindex;
if (!nh.type) {
nh.type = ifindex ? NEXTHOP_TYPE_IPV6_IFINDEX
: NEXTHOP_TYPE_IPV6;
nh.gate.ipv6 = gate.sin6.sin6_addr;
nh.ifindex = ifindex;
}
if (rtm->rtm_type == RTM_GET || rtm->rtm_type == RTM_ADD
|| rtm->rtm_type == RTM_CHANGE)
@ -1088,7 +1094,7 @@ void rtm_read(struct rt_msghdr *rtm)
*/
int rtm_write(int message, union sockunion *dest, union sockunion *mask,
union sockunion *gate, union sockunion *mpls, unsigned int index,
int zebra_flags, int metric)
enum blackhole_type bh_type, int metric)
{
int ret;
caddr_t pnt;
@ -1178,11 +1184,16 @@ int rtm_write(int message, union sockunion *dest, union sockunion *mask,
/* Tagging route with flags */
msg.rtm.rtm_flags |= (RTF_PROTO1);
/* Additional flags. */
if (zebra_flags & ZEBRA_FLAG_BLACKHOLE)
msg.rtm.rtm_flags |= RTF_BLACKHOLE;
if (zebra_flags & ZEBRA_FLAG_REJECT)
switch (bh_type) {
case BLACKHOLE_UNSPEC:
break;
case BLACKHOLE_REJECT:
msg.rtm.rtm_flags |= RTF_REJECT;
break;
default:
msg.rtm.rtm_flags |= RTF_BLACKHOLE;
break;
}
#define SOCKADDRSET(X, R) \

View file

@ -34,8 +34,8 @@ extern void rtm_read(struct rt_msghdr *);
extern int ifam_read(struct ifa_msghdr *);
extern int ifm_read(struct if_msghdr *);
extern int rtm_write(int, union sockunion *, union sockunion *,
union sockunion *, union sockunion *, unsigned int, int,
int);
union sockunion *, union sockunion *, unsigned int,
enum blackhole_type, int);
extern const struct message rtm_type_str[];
#endif /* __ZEBRA_KERNEL_SOCKET_H */

View file

@ -231,7 +231,8 @@ typedef enum {
extern struct nexthop *route_entry_nexthop_ifindex_add(struct route_entry *,
ifindex_t);
extern struct nexthop *route_entry_nexthop_blackhole_add(struct route_entry *);
extern struct nexthop *route_entry_nexthop_blackhole_add(struct route_entry *,
enum blackhole_type);
extern struct nexthop *route_entry_nexthop_ipv4_add(struct route_entry *,
struct in_addr *,
struct in_addr *);

View file

@ -1221,7 +1221,7 @@ static int netlink_route_multipath(int cmd, struct prefix *p,
struct sockaddr_nl snl;
struct nexthop *nexthop = NULL;
unsigned int nexthop_num;
int discard;
int discard = 0;
int family = PREFIX_FAMILY(p);
const char *routedesc;
int setsrc = 0;
@ -1252,24 +1252,23 @@ static int netlink_route_multipath(int cmd, struct prefix *p,
req.r.rtm_src_len = src_p ? src_p->prefixlen : 0;
req.r.rtm_protocol = get_rt_proto(re->type);
req.r.rtm_scope = RT_SCOPE_UNIVERSE;
req.r.rtm_type = RTN_UNICAST;
if ((re->flags & ZEBRA_FLAG_BLACKHOLE)
|| (re->flags & ZEBRA_FLAG_REJECT))
if (re->nexthop_num == 1
&& re->nexthop->type == NEXTHOP_TYPE_BLACKHOLE) {
discard = 1;
else
discard = 0;
if (cmd == RTM_NEWROUTE) {
if (discard) {
if (re->flags & ZEBRA_FLAG_BLACKHOLE)
req.r.rtm_type = RTN_BLACKHOLE;
else if (re->flags & ZEBRA_FLAG_REJECT)
req.r.rtm_type = RTN_UNREACHABLE;
else
assert(RTN_BLACKHOLE
!= RTN_UNREACHABLE); /* false */
} else
req.r.rtm_type = RTN_UNICAST;
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);
@ -1294,6 +1293,9 @@ static int netlink_route_multipath(int cmd, struct prefix *p,
addattr32(&req.n, sizeof req, RTA_TABLE, re->table);
}
if (discard)
goto skip;
if (re->mtu || re->nexthop_mtu) {
char buf[NL_PKT_BUF_SIZE];
struct rtattr *rta = (void *)buf;
@ -1307,21 +1309,6 @@ static int netlink_route_multipath(int cmd, struct prefix *p,
RTA_PAYLOAD(rta));
}
if (discard) {
if (cmd == RTM_NEWROUTE)
for (ALL_NEXTHOPS(re->nexthop, nexthop)) {
/* We shouldn't encounter recursive nexthops on
* discard routes,
* but it is probably better to handle that case
* correctly anyway.
*/
if (CHECK_FLAG(nexthop->flags,
NEXTHOP_FLAG_RECURSIVE))
continue;
}
goto skip;
}
/* Count overall nexthops so we can decide whether to use singlepath
* or multipath case. */
nexthop_num = 0;

View file

@ -42,11 +42,6 @@
extern struct zebra_privs_t zserv_privs;
/* kernel socket export */
extern int rtm_write(int message, union sockunion *dest, union sockunion *mask,
union sockunion *gate, union sockunion *mpls,
unsigned int index, int zebra_flags, int metric);
#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
/* Adjust netmask socket length. Return value is a adjusted sin_len
value. */
@ -108,6 +103,7 @@ static int kernel_rtm_ipv4(int cmd, struct prefix *p, struct route_entry *re)
int gate = 0;
int error;
char prefix_buf[PREFIX_STRLEN];
enum blackhole_type bh_type = BLACKHOLE_UNSPEC;
if (IS_ZEBRA_DEBUG_RIB)
prefix2str(p, prefix_buf, sizeof(prefix_buf));
@ -155,6 +151,7 @@ static int kernel_rtm_ipv4(int cmd, struct prefix *p, struct route_entry *re)
struct in_addr loopback;
loopback.s_addr = htonl(INADDR_LOOPBACK);
sin_gate.sin_addr = loopback;
bh_type = nexthop->bh_type;
gate = 1;
}
@ -182,7 +179,7 @@ static int kernel_rtm_ipv4(int cmd, struct prefix *p, struct route_entry *re)
cmd, (union sockunion *)&sin_dest,
(union sockunion *)mask,
gate ? (union sockunion *)&sin_gate : NULL,
smplsp, ifindex, re->flags, re->metric);
smplsp, ifindex, bh_type, re->metric);
if (IS_ZEBRA_DEBUG_RIB) {
if (!gate) {
@ -292,6 +289,7 @@ static int kernel_rtm_ipv6(int cmd, struct prefix *p, struct route_entry *re)
ifindex_t ifindex = 0;
int gate = 0;
int error;
enum blackhole_type bh_type = BLACKHOLE_UNSPEC;
memset(&sin_dest, 0, sizeof(struct sockaddr_in6));
sin_dest.sin6_family = AF_INET6;
@ -331,6 +329,9 @@ static int kernel_rtm_ipv6(int cmd, struct prefix *p, struct route_entry *re)
|| nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX)
ifindex = nexthop->ifindex;
if (nexthop->type == NEXTHOP_TYPE_BLACKHOLE)
bh_type = nexthop->bh_type;
if (cmd == RTM_ADD)
SET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB);
}
@ -369,7 +370,7 @@ static int kernel_rtm_ipv6(int cmd, struct prefix *p, struct route_entry *re)
error = rtm_write(cmd, (union sockunion *)&sin_dest,
(union sockunion *)mask,
gate ? (union sockunion *)&sin_gate : NULL,
smplsp, ifindex, re->flags, re->metric);
smplsp, ifindex, bh_type, re->metric);
#if 0
if (error)

View file

@ -222,7 +222,6 @@ static int netlink_route_info_fill(netlink_route_info_t *ri, int cmd,
rib_dest_t *dest, struct route_entry *re)
{
struct nexthop *nexthop;
int discard;
memset(ri, 0, sizeof(*ri));
@ -247,30 +246,9 @@ static int netlink_route_info_fill(netlink_route_info_t *ri, int cmd,
}
ri->rtm_protocol = netlink_proto_from_route_type(re->type);
if ((re->flags & ZEBRA_FLAG_BLACKHOLE)
|| (re->flags & ZEBRA_FLAG_REJECT))
discard = 1;
else
discard = 0;
if (cmd == RTM_NEWROUTE) {
if (discard) {
if (re->flags & ZEBRA_FLAG_BLACKHOLE)
ri->rtm_type = RTN_BLACKHOLE;
else if (re->flags & ZEBRA_FLAG_REJECT)
ri->rtm_type = RTN_UNREACHABLE;
else
assert(0);
} else
ri->rtm_type = RTN_UNICAST;
}
ri->rtm_type = RTN_UNICAST;
ri->metric = &re->metric;
if (discard)
return 1;
for (ALL_NEXTHOPS(re->nexthop, nexthop)) {
if (ri->num_nhs >= multipath_num)
break;
@ -278,6 +256,22 @@ static int netlink_route_info_fill(netlink_route_info_t *ri, int cmd,
if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
continue;
if (nexthop->type == NEXTHOP_TYPE_BLACKHOLE) {
switch (nexthop->bh_type) {
case BLACKHOLE_ADMINPROHIB:
ri->rtm_type = RTN_PROHIBIT;
break;
case BLACKHOLE_REJECT:
ri->rtm_type = RTN_UNREACHABLE;
break;
case BLACKHOLE_NULL:
default:
ri->rtm_type = RTN_BLACKHOLE;
break;
}
return 1;
}
if ((cmd == RTM_NEWROUTE
&& CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE))
|| (cmd == RTM_DELROUTE

View file

@ -141,7 +141,6 @@ static Fpm__AddRoute *create_add_route_message(qpb_allocator_t *allocator,
struct route_entry *re)
{
Fpm__AddRoute *msg;
int discard;
struct nexthop *nexthop;
uint num_nhs, u;
struct nexthop *nexthops[MULTIPATH_NUM];
@ -164,26 +163,7 @@ static Fpm__AddRoute *create_add_route_message(qpb_allocator_t *allocator,
msg->sub_address_family = QPB__SUB_ADDRESS_FAMILY__UNICAST;
msg->key = fpm_route_key_create(allocator, rib_dest_prefix(dest));
qpb_protocol_set(&msg->protocol, re->type);
if ((re->flags & ZEBRA_FLAG_BLACKHOLE)
|| (re->flags & ZEBRA_FLAG_REJECT))
discard = 1;
else
discard = 0;
if (discard) {
if (re->flags & ZEBRA_FLAG_BLACKHOLE) {
msg->route_type = FPM__ROUTE_TYPE__BLACKHOLE;
} else if (re->flags & ZEBRA_FLAG_REJECT) {
msg->route_type = FPM__ROUTE_TYPE__UNREACHABLE;
} else {
assert(0);
}
return msg;
} else {
msg->route_type = FPM__ROUTE_TYPE__NORMAL;
}
msg->route_type = FPM__ROUTE_TYPE__NORMAL;
msg->metric = re->metric;
/*
@ -197,6 +177,19 @@ static Fpm__AddRoute *create_add_route_message(qpb_allocator_t *allocator,
if (num_nhs >= ZEBRA_NUM_OF(nexthops))
break;
if (nexthop->type == NEXTHOP_TYPE_BLACKHOLE) {
switch (nexthop->bh_type) {
case BLACKHOLE_REJECT:
msg->route_type = FPM__ROUTE_TYPE__UNREACHABLE;
break;
case BLACKHOLE_NULL:
default:
msg->route_type = FPM__ROUTE_TYPE__BLACKHOLE;
break;
}
return msg;
}
if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
continue;

View file

@ -291,13 +291,14 @@ struct nexthop *route_entry_nexthop_ipv6_ifindex_add(struct route_entry *re,
return nexthop;
}
struct nexthop *route_entry_nexthop_blackhole_add(struct route_entry *re)
struct nexthop *route_entry_nexthop_blackhole_add(struct route_entry *re,
enum blackhole_type bh_type)
{
struct nexthop *nexthop;
nexthop = nexthop_new();
nexthop->type = NEXTHOP_TYPE_BLACKHOLE;
SET_FLAG(re->flags, ZEBRA_FLAG_BLACKHOLE);
nexthop->bh_type = bh_type;
route_entry_nexthop_add(re, nexthop);
@ -471,12 +472,6 @@ static int nexthop_active(afi_t afi, struct route_entry *re,
continue;
}
/* If the longest prefix match for the nexthop yields
* a blackhole, mark it as inactive. */
if (CHECK_FLAG(match->flags, ZEBRA_FLAG_BLACKHOLE)
|| CHECK_FLAG(match->flags, ZEBRA_FLAG_REJECT))
return 0;
if (match->type == ZEBRA_ROUTE_CONNECT) {
/* Directly point connected route. */
newhop = match->nexthop;
@ -488,41 +483,46 @@ static int nexthop_active(afi_t afi, struct route_entry *re,
return 1;
} else if (CHECK_FLAG(re->flags, ZEBRA_FLAG_INTERNAL)) {
resolved = 0;
for (ALL_NEXTHOPS(match->nexthop, newhop))
if (CHECK_FLAG(newhop->flags, NEXTHOP_FLAG_FIB)
&& !CHECK_FLAG(newhop->flags,
NEXTHOP_FLAG_RECURSIVE)) {
if (set) {
SET_FLAG(
nexthop->flags,
NEXTHOP_FLAG_RECURSIVE);
SET_FLAG(
re->status,
ROUTE_ENTRY_NEXTHOPS_CHANGED);
for (ALL_NEXTHOPS(match->nexthop, newhop)) {
if (newhop->type == NEXTHOP_TYPE_BLACKHOLE)
continue;
if (!CHECK_FLAG(newhop->flags,
NEXTHOP_FLAG_FIB))
continue;
if (CHECK_FLAG(newhop->flags,
NEXTHOP_FLAG_RECURSIVE))
continue;
nexthop_set_resolved(
afi, newhop, nexthop);
}
resolved = 1;
if (set) {
SET_FLAG(nexthop->flags,
NEXTHOP_FLAG_RECURSIVE);
SET_FLAG(re->status,
ROUTE_ENTRY_NEXTHOPS_CHANGED);
nexthop_set_resolved(afi, newhop,
nexthop);
}
resolved = 1;
}
if (resolved && set)
re->nexthop_mtu = match->mtu;
return resolved;
} else if (re->type == ZEBRA_ROUTE_STATIC) {
resolved = 0;
for (ALL_NEXTHOPS(match->nexthop, newhop))
if (CHECK_FLAG(newhop->flags,
NEXTHOP_FLAG_FIB)) {
if (set) {
SET_FLAG(
nexthop->flags,
NEXTHOP_FLAG_RECURSIVE);
for (ALL_NEXTHOPS(match->nexthop, newhop)) {
if (newhop->type == NEXTHOP_TYPE_BLACKHOLE)
continue;
if (!CHECK_FLAG(newhop->flags,
NEXTHOP_FLAG_FIB))
continue;
nexthop_set_resolved(
afi, newhop, nexthop);
}
resolved = 1;
if (set) {
SET_FLAG(nexthop->flags,
NEXTHOP_FLAG_RECURSIVE);
nexthop_set_resolved(afi, newhop,
nexthop);
}
resolved = 1;
}
if (resolved && set)
re->nexthop_mtu = match->mtu;
return resolved;

View file

@ -91,7 +91,8 @@ void static_install_route(afi_t afi, safi_t safi, struct prefix *p,
si->ifindex);
break;
case STATIC_BLACKHOLE:
nexthop = route_entry_nexthop_blackhole_add(re);
nexthop = route_entry_nexthop_blackhole_add(re,
si->bh_type);
break;
case STATIC_IPV6_GATEWAY:
nexthop = route_entry_nexthop_ipv6_add(re,
@ -166,7 +167,8 @@ void static_install_route(afi_t afi, safi_t safi, struct prefix *p,
si->ifindex);
break;
case STATIC_BLACKHOLE:
nexthop = route_entry_nexthop_blackhole_add(re);
nexthop = route_entry_nexthop_blackhole_add(re,
si->bh_type);
break;
case STATIC_IPV6_GATEWAY:
nexthop = route_entry_nexthop_ipv6_add(re,
@ -187,9 +189,6 @@ void static_install_route(afi_t afi, safi_t safi, struct prefix *p,
si->snh_label.num_labels,
&si->snh_label.label[0]);
/* Save the flags of this static routes (reject, blackhole) */
re->flags = si->flags;
if (IS_ZEBRA_DEBUG_RIB) {
char buf[INET6_ADDRSTRLEN];
if (IS_ZEBRA_DEBUG_RIB) {
@ -364,7 +363,7 @@ void static_uninstall_route(afi_t afi, safi_t safi, struct prefix *p,
int static_add_route(afi_t afi, safi_t safi, u_char type, struct prefix *p,
struct prefix_ipv6 *src_p, union g_addr *gate,
const char *ifname, u_char flags,
const char *ifname, enum blackhole_type bh_type,
route_tag_t tag, u_char distance, struct zebra_vrf *zvrf,
struct static_nh_label *snh_label)
{
@ -405,7 +404,7 @@ int static_add_route(afi_t afi, safi_t safi, u_char type, struct prefix *p,
if ((distance == si->distance) && (tag == si->tag)
&& !memcmp(&si->snh_label, snh_label,
sizeof(struct static_nh_label))
&& si->flags == flags) {
&& si->bh_type == bh_type) {
route_unlock_node(rn);
return 0;
} else
@ -424,7 +423,7 @@ int static_add_route(afi_t afi, safi_t safi, u_char type, struct prefix *p,
si->type = type;
si->distance = distance;
si->flags = flags;
si->bh_type = bh_type;
si->tag = tag;
si->vrf_id = zvrf_id(zvrf);
if (ifname)

View file

@ -61,18 +61,12 @@ struct static_route {
/*
* Nexthop value.
*/
enum blackhole_type bh_type;
union g_addr addr;
ifindex_t ifindex;
char ifname[INTERFACE_NAMSIZ + 1];
/* bit flags */
u_char flags;
/*
see ZEBRA_FLAG_REJECT
ZEBRA_FLAG_BLACKHOLE
*/
/* Label information */
struct static_nh_label snh_label;
};
@ -86,7 +80,7 @@ extern void static_uninstall_route(afi_t afi, safi_t safi, struct prefix *p,
extern int static_add_route(afi_t, safi_t safi, u_char type, struct prefix *p,
struct prefix_ipv6 *src_p, union g_addr *gate,
const char *ifname, u_char flags,
const char *ifname, enum blackhole_type bh_type,
route_tag_t tag, u_char distance,
struct zebra_vrf *zvrf,
struct static_nh_label *snh_label);

View file

@ -74,7 +74,7 @@ static int zebra_static_route(struct vty *vty, afi_t afi, safi_t safi,
union g_addr gate;
union g_addr *gatep = NULL;
struct in_addr mask;
u_char flag = 0;
enum blackhole_type bh_type = 0;
route_tag_t tag = 0;
struct zebra_vrf *zvrf;
u_char type;
@ -165,28 +165,18 @@ static int zebra_static_route(struct vty *vty, afi_t afi, safi_t safi,
}
}
/* Null0 static route. */
if ((ifname != NULL)
&& (strncasecmp(ifname, "Null0", strlen(ifname)) == 0)) {
if (flag_str) {
vty_out(vty, "%% can not have flag %s with Null0\n",
flag_str);
return CMD_WARNING_CONFIG_FAILED;
}
SET_FLAG(flag, ZEBRA_FLAG_BLACKHOLE);
ifname = NULL;
}
/* Route flags */
if (flag_str) {
switch (flag_str[0]) {
case 'r':
case 'R': /* XXX */
SET_FLAG(flag, ZEBRA_FLAG_REJECT);
bh_type = BLACKHOLE_REJECT;
break;
case 'n':
case 'N' /* XXX */:
case 'b':
case 'B': /* XXX */
SET_FLAG(flag, ZEBRA_FLAG_BLACKHOLE);
bh_type = BLACKHOLE_NULL;
break;
default:
vty_out(vty, "%% Malformed flag %s \n", flag_str);
@ -221,7 +211,7 @@ static int zebra_static_route(struct vty *vty, afi_t afi, safi_t safi,
if (!negate)
static_add_route(afi, safi, type, &p, src_p, gatep, ifname,
flag, tag, distance, zvrf, &snh_label);
bh_type, tag, distance, zvrf, &snh_label);
else
static_delete_route(afi, safi, type, &p, src_p, gatep, ifname,
tag, distance, zvrf, &snh_label);
@ -346,8 +336,7 @@ DEFPY (ip_route,
<A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask>\
<\
{A.B.C.D$gate|INTERFACE$ifname}\
|null0$ifname\
|<reject|blackhole>$flag\
|<null0|reject|blackhole>$flag\
>\
[{\
tag (1-4294967295)\
@ -417,10 +406,6 @@ static void vty_show_ip_route_detail(struct vty *vty, struct route_node *rn,
vty_out(vty, ", best");
if (re->refcnt)
vty_out(vty, ", refcnt %ld", re->refcnt);
if (CHECK_FLAG(re->flags, ZEBRA_FLAG_BLACKHOLE))
vty_out(vty, ", blackhole");
if (CHECK_FLAG(re->flags, ZEBRA_FLAG_REJECT))
vty_out(vty, ", reject");
vty_out(vty, "\n");
if (re->type == ZEBRA_ROUTE_RIP || re->type == ZEBRA_ROUTE_OSPF
@ -485,7 +470,20 @@ static void vty_show_ip_route_detail(struct vty *vty, struct route_node *rn,
re->vrf_id));
break;
case NEXTHOP_TYPE_BLACKHOLE:
vty_out(vty, " directly connected, Null0");
vty_out(vty, " unreachable");
switch (nexthop->bh_type) {
case BLACKHOLE_REJECT:
vty_out(vty, " (ICMP unreachable)");
break;
case BLACKHOLE_ADMINPROHIB:
vty_out(vty, " (ICMP admin-prohibited)");
break;
case BLACKHOLE_NULL:
vty_out(vty, " (blackhole)");
break;
case BLACKHOLE_UNSPEC:
break;
}
break;
default:
break;
@ -580,12 +578,6 @@ static void vty_show_ip_route(struct vty *vty, struct route_node *rn,
json_object_int_add(json_route, "metric", re->metric);
}
if (CHECK_FLAG(re->flags, ZEBRA_FLAG_BLACKHOLE))
json_object_boolean_true_add(json_route, "blackhole");
if (CHECK_FLAG(re->flags, ZEBRA_FLAG_REJECT))
json_object_boolean_true_add(json_route, "reject");
if (re->type == ZEBRA_ROUTE_RIP || re->type == ZEBRA_ROUTE_OSPF
|| re->type == ZEBRA_ROUTE_ISIS
|| re->type == ZEBRA_ROUTE_NHRP
@ -671,7 +663,26 @@ static void vty_show_ip_route(struct vty *vty, struct route_node *rn,
break;
case NEXTHOP_TYPE_BLACKHOLE:
json_object_boolean_true_add(json_nexthop,
"blackhole");
"unreachable");
switch (nexthop->bh_type) {
case BLACKHOLE_REJECT:
json_object_boolean_true_add(
json_nexthop,
"reject");
break;
case BLACKHOLE_ADMINPROHIB:
json_object_boolean_true_add(
json_nexthop,
"admin-prohibited");
break;
case BLACKHOLE_NULL:
json_object_boolean_true_add(
json_nexthop,
"blackhole");
break;
case BLACKHOLE_UNSPEC:
break;
}
break;
default:
break;
@ -796,7 +807,20 @@ static void vty_show_ip_route(struct vty *vty, struct route_node *rn,
ifindex2ifname(nexthop->ifindex, re->vrf_id));
break;
case NEXTHOP_TYPE_BLACKHOLE:
vty_out(vty, " is directly connected, Null0");
vty_out(vty, " unreachable");
switch (nexthop->bh_type) {
case BLACKHOLE_REJECT:
vty_out(vty, " (ICMP unreachable)");
break;
case BLACKHOLE_ADMINPROHIB:
vty_out(vty, " (ICMP admin-prohibited)");
break;
case BLACKHOLE_NULL:
vty_out(vty, " (blackhole)");
break;
case BLACKHOLE_UNSPEC:
break;
}
break;
default:
break;
@ -839,11 +863,6 @@ static void vty_show_ip_route(struct vty *vty, struct route_node *rn,
sizeof buf, 1));
}
if (CHECK_FLAG(re->flags, ZEBRA_FLAG_BLACKHOLE))
vty_out(vty, ", bh");
if (CHECK_FLAG(re->flags, ZEBRA_FLAG_REJECT))
vty_out(vty, ", rej");
if (re->type == ZEBRA_ROUTE_RIP || re->type == ZEBRA_ROUTE_OSPF
|| re->type == ZEBRA_ROUTE_ISIS
|| re->type == ZEBRA_ROUTE_NHRP
@ -1693,12 +1712,15 @@ static int static_config(struct vty *vty, afi_t afi, safi_t safi,
case STATIC_IFNAME:
vty_out(vty, " %s", si->ifname);
break;
/* blackhole and Null0 mean the same thing */
case STATIC_BLACKHOLE:
if (CHECK_FLAG(si->flags, ZEBRA_FLAG_REJECT))
switch (si->bh_type) {
case BLACKHOLE_REJECT:
vty_out(vty, " reject");
else
vty_out(vty, " Null0");
break;
default:
vty_out(vty, " blackhole");
break;
}
break;
case STATIC_IPV4_GATEWAY_IFNAME:
vty_out(vty, " %s %s",
@ -1716,19 +1738,6 @@ static int static_config(struct vty *vty, afi_t afi, safi_t safi,
break;
}
/* flags are incompatible with STATIC_BLACKHOLE
*/
if (si->type != STATIC_BLACKHOLE) {
if (CHECK_FLAG(si->flags,
ZEBRA_FLAG_REJECT))
vty_out(vty, " %s", "reject");
if (CHECK_FLAG(si->flags,
ZEBRA_FLAG_BLACKHOLE))
vty_out(vty, " %s",
"blackhole");
}
if (si->tag)
vty_out(vty, " tag %" ROUTE_TAG_PRI,
si->tag);
@ -1763,8 +1772,7 @@ DEFPY (ipv6_route,
"[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M]\
<\
{X:X::X:X$gate|INTERFACE$ifname}\
|null0$ifname\
|<reject|blackhole>$flag\
|<null0|reject|blackhole>$flag\
>\
[{\
tag (1-4294967295)\

View file

@ -1051,6 +1051,7 @@ static int zread_route_add(struct zserv *client, u_short length,
struct route_entry *re;
struct nexthop *nexthop = NULL;
int i, ret;
enum blackhole_type bh_type = BLACKHOLE_NULL;
s = client->ibuf;
if (zapi_route_decode(s, &api) < 0)
@ -1093,7 +1094,7 @@ static int zread_route_add(struct zserv *client, u_short length,
api_nh->ifindex);
break;
case NEXTHOP_TYPE_BLACKHOLE:
route_entry_nexthop_blackhole_add(re);
route_entry_nexthop_blackhole_add(re, bh_type);
break;
}
@ -1163,7 +1164,7 @@ static int zread_route_del(struct zserv *client, u_short length,
src_p = &api.src_prefix;
rib_delete(afi, api.safi, zvrf_id(zvrf), api.type, api.instance,
api.flags, &api.prefix, src_p, NULL, 0, zvrf->table_id,
api.flags, &api.prefix, src_p, NULL, zvrf->table_id,
api.metric);
/* Stats */
@ -1201,6 +1202,7 @@ static int zread_ipv4_add(struct zserv *client, u_short length,
enum lsp_types_t label_type = ZEBRA_LSP_NONE;
mpls_label_t label;
struct nexthop *nexthop;
enum blackhole_type bh_type = BLACKHOLE_NULL;
/* Get input stream. */
s = client->ibuf;
@ -1264,7 +1266,7 @@ static int zread_ipv4_add(struct zserv *client, u_short length,
stream_forward_getp(s, IPV6_MAX_BYTELEN);
break;
case NEXTHOP_TYPE_BLACKHOLE:
route_entry_nexthop_blackhole_add(re);
route_entry_nexthop_blackhole_add(re, bh_type);
break;
}
}
@ -1329,7 +1331,7 @@ static int zread_ipv4_delete(struct zserv *client, u_short length,
table_id = zvrf->table_id;
rib_delete(AFI_IP, api.safi, zvrf_id(zvrf), api.type, api.instance,
api.flags, &p, NULL, NULL, 0, table_id, 0);
api.flags, &p, NULL, NULL, table_id, 0);
client->v4_route_del_cnt++;
return 0;
}
@ -1367,6 +1369,7 @@ static int zread_ipv4_route_ipv6_nexthop_add(struct zserv *client,
enum lsp_types_t label_type = ZEBRA_LSP_NONE;
mpls_label_t label;
struct nexthop *nexthop;
enum blackhole_type bh_type = BLACKHOLE_NULL;
/* Get input stream. */
s = client->ibuf;
@ -1434,7 +1437,7 @@ static int zread_ipv4_route_ipv6_nexthop_add(struct zserv *client,
}
break;
case NEXTHOP_TYPE_BLACKHOLE:
route_entry_nexthop_blackhole_add(re);
route_entry_nexthop_blackhole_add(re, bh_type);
break;
}
}
@ -1516,6 +1519,7 @@ static int zread_ipv6_add(struct zserv *client, u_short length,
enum lsp_types_t label_type = ZEBRA_LSP_NONE;
mpls_label_t label;
struct nexthop *nexthop;
enum blackhole_type bh_type = BLACKHOLE_NULL;
/* Get input stream. */
s = client->ibuf;
@ -1594,7 +1598,7 @@ static int zread_ipv6_add(struct zserv *client, u_short length,
}
break;
case NEXTHOP_TYPE_BLACKHOLE:
route_entry_nexthop_blackhole_add(re);
route_entry_nexthop_blackhole_add(re, bh_type);
break;
}
}
@ -1689,7 +1693,7 @@ static int zread_ipv6_delete(struct zserv *client, u_short length,
src_pp = NULL;
rib_delete(AFI_IP6, api.safi, zvrf_id(zvrf), api.type, api.instance,
api.flags, &p, src_pp, NULL, 0, client->rtm_table, 0);
api.flags, &p, src_pp, NULL, client->rtm_table, 0);
client->v6_route_del_cnt++;
return 0;