From a830942228110cbec0e857d0877d624206627f81 Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Fri, 5 Feb 2010 04:31:56 +0100 Subject: [PATCH] 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 --- lib/nexthop.h | 5 +- lib/zebra.h | 4 +- zebra/kernel_socket.c | 47 +++++++++------ zebra/kernel_socket.h | 4 +- zebra/rib.h | 3 +- zebra/rt_netlink.c | 51 ++++++---------- zebra/rt_socket.c | 15 ++--- zebra/zebra_fpm_netlink.c | 40 ++++++------- zebra/zebra_fpm_protobuf.c | 35 +++++------ zebra/zebra_rib.c | 70 +++++++++++----------- zebra/zebra_static.c | 15 +++-- zebra/zebra_static.h | 10 +--- zebra/zebra_vty.c | 118 ++++++++++++++++++++----------------- zebra/zserv.c | 18 +++--- 14 files changed, 215 insertions(+), 220 deletions(-) diff --git a/lib/nexthop.h b/lib/nexthop.h index 7cfba5c5b6..781eb93413 100644 --- a/lib/nexthop.h +++ b/lib/nexthop.h @@ -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 */ diff --git a/lib/zebra.h b/lib/zebra.h index 6d64bbd670..fa5fa89f77 100644 --- a/lib/zebra.h +++ b/lib/zebra.h @@ -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 diff --git a/zebra/kernel_socket.c b/zebra/kernel_socket.c index ee21e61fe7..7802a9d207 100644 --- a/zebra/kernel_socket.c +++ b/zebra/kernel_socket.c @@ -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) \ diff --git a/zebra/kernel_socket.h b/zebra/kernel_socket.h index 41b322185f..096a21f782 100644 --- a/zebra/kernel_socket.h +++ b/zebra/kernel_socket.h @@ -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 */ diff --git a/zebra/rib.h b/zebra/rib.h index 9e456e436f..9b1ce23b08 100644 --- a/zebra/rib.h +++ b/zebra/rib.h @@ -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 *); diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index ec19c53b73..fa38c21abf 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -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; diff --git a/zebra/rt_socket.c b/zebra/rt_socket.c index 32ae41b917..10c7109194 100644 --- a/zebra/rt_socket.c +++ b/zebra/rt_socket.c @@ -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) diff --git a/zebra/zebra_fpm_netlink.c b/zebra/zebra_fpm_netlink.c index 28f7956639..27c7891372 100644 --- a/zebra/zebra_fpm_netlink.c +++ b/zebra/zebra_fpm_netlink.c @@ -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 diff --git a/zebra/zebra_fpm_protobuf.c b/zebra/zebra_fpm_protobuf.c index 450ad5b0bf..b850f1fb1e 100644 --- a/zebra/zebra_fpm_protobuf.c +++ b/zebra/zebra_fpm_protobuf.c @@ -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; diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index 644f48793a..eecefa09c8 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -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); - - 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; diff --git a/zebra/zebra_static.c b/zebra/zebra_static.c index 6815916faf..51bbf2a0cc 100644 --- a/zebra/zebra_static.c +++ b/zebra/zebra_static.c @@ -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) diff --git a/zebra/zebra_static.h b/zebra/zebra_static.h index ff9f0f59e7..458594a289 100644 --- a/zebra/zebra_static.h +++ b/zebra/zebra_static.h @@ -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); diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c index 9f887e8401..d9ef81e97c 100644 --- a/zebra/zebra_vty.c +++ b/zebra/zebra_vty.c @@ -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$gate|INTERFACE$ifname}\ - |null0$ifname\ - |$flag\ + |$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\ - |$flag\ + |$flag\ >\ [{\ tag (1-4294967295)\ diff --git a/zebra/zserv.c b/zebra/zserv.c index 0e0cc78bbe..46dfe37818 100644 --- a/zebra/zserv.c +++ b/zebra/zserv.c @@ -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; -- 2.39.5