#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 */
/* 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
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;
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)
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)
*/
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;
/* 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) \
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 */
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 *);
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;
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);
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;
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;
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. */
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));
struct in_addr loopback;
loopback.s_addr = htonl(INADDR_LOOPBACK);
sin_gate.sin_addr = loopback;
+ bh_type = nexthop->bh_type;
gate = 1;
}
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) {
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;
|| 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);
}
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)
rib_dest_t *dest, struct route_entry *re)
{
struct nexthop *nexthop;
- int discard;
memset(ri, 0, sizeof(*ri));
}
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;
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
struct route_entry *re)
{
Fpm__AddRoute *msg;
- int discard;
struct nexthop *nexthop;
uint num_nhs, u;
struct nexthop *nexthops[MULTIPATH_NUM];
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;
/*
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;
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);
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;
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);
-
- nexthop_set_resolved(
- afi, newhop, nexthop);
- }
- resolved = 1;
+ 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;
+
+ 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;
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,
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,
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) {
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)
{
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
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)
/*
* 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;
};
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);
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;
}
}
- /* 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);
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);
<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)\
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
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;
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
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;
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;
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
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",
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);
"[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)\
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)
api_nh->ifindex);
break;
case NEXTHOP_TYPE_BLACKHOLE:
- route_entry_nexthop_blackhole_add(re);
+ route_entry_nexthop_blackhole_add(re, bh_type);
break;
}
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 */
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;
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;
}
}
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;
}
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;
}
break;
case NEXTHOP_TYPE_BLACKHOLE:
- route_entry_nexthop_blackhole_add(re);
+ route_entry_nexthop_blackhole_add(re, bh_type);
break;
}
}
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;
}
break;
case NEXTHOP_TYPE_BLACKHOLE:
- route_entry_nexthop_blackhole_add(re);
+ route_entry_nexthop_blackhole_add(re, bh_type);
break;
}
}
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;