diff --git a/babeld/kernel.c b/babeld/kernel.c index 394d7b1e81..3343ca2e95 100644 --- a/babeld/kernel.c +++ b/babeld/kernel.c @@ -169,7 +169,7 @@ zebra_route(int add, int family, const unsigned char *pref, unsigned short plen, api.prefix = quagga_prefix; if(metric >= KERNEL_INFINITY) { - api.flags = ZEBRA_FLAG_REJECT; + zapi_route_set_blackhole(&api, BLACKHOLE_REJECT); } else { SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); api.nexthop_num = 1; diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index 9a092404d5..8b9d55295d 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -1022,7 +1022,7 @@ void bgp_zebra_announce(struct bgp_node *rn, struct prefix *p, * in * the RIB */ if (info->sub_type == BGP_ROUTE_AGGREGATE) - SET_FLAG(api.flags, ZEBRA_FLAG_BLACKHOLE); + zapi_route_set_blackhole(&api, BLACKHOLE_NULL); if (peer->sort == BGP_PEER_IBGP || peer->sort == BGP_PEER_CONFED || info->sub_type == BGP_ROUTE_AGGREGATE) { @@ -1152,7 +1152,7 @@ void bgp_zebra_announce(struct bgp_node *rn, struct prefix *p, if (has_valid_label) SET_FLAG(api.message, ZAPI_MESSAGE_LABEL); - if (!CHECK_FLAG(api.flags, ZEBRA_FLAG_BLACKHOLE)) + if (info->sub_type != BGP_ROUTE_AGGREGATE) api.nexthop_num = valid_nh_count; SET_FLAG(api.message, ZAPI_MESSAGE_METRIC); diff --git a/lib/nexthop.h b/lib/nexthop.h index e7804379f1..12a1203a8f 100644 --- a/lib/nexthop.h +++ b/lib/nexthop.h @@ -43,6 +43,13 @@ enum nexthop_types_t { NEXTHOP_TYPE_BLACKHOLE, /* Null0 nexthop. */ }; +enum blackhole_type { + BLACKHOLE_UNSPEC = 0, + BLACKHOLE_NULL, + BLACKHOLE_REJECT, + BLACKHOLE_ADMINPROHIB, +}; + /* Nexthop label structure. */ struct nexthop_label { u_int8_t num_labels; diff --git a/lib/zclient.c b/lib/zclient.c index 72fa2679b3..992b254939 100644 --- a/lib/zclient.c +++ b/lib/zclient.c @@ -621,10 +621,9 @@ static int zclient_connect(struct thread *t) * | IPv4 Nexthop address or Interface Index number | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * - * Alternatively, if the flags field has ZEBRA_FLAG_BLACKHOLE or - * ZEBRA_FLAG_REJECT is set then Nexthop count is set to 1, then _no_ - * nexthop information is provided, and the message describes a prefix - * to blackhole or reject route. + * Alternatively, if the route is a blackhole route, then Nexthop count + * is set to 1 and a nexthop of type NEXTHOP_TYPE_BLACKHOLE is the sole + * nexthop. * * The original struct zapi_ipv4, zapi_ipv4_route() and zread_ipv4_*() * infrastructure was built around the traditional (32-bit "gate OR @@ -692,14 +691,7 @@ int zapi_ipv4_route(u_char cmd, struct zclient *zclient, struct prefix_ipv4 *p, /* Nexthop, ifindex, distance and metric information. */ if (CHECK_FLAG(api->message, ZAPI_MESSAGE_NEXTHOP)) { - /* traditional 32-bit data units */ - if (CHECK_FLAG(api->flags, ZEBRA_FLAG_BLACKHOLE)) { - stream_putc(s, 1); - stream_putc(s, NEXTHOP_TYPE_BLACKHOLE); - /* XXX assert(api->nexthop_num == 0); */ - /* XXX assert(api->ifindex_num == 0); */ - } else - stream_putc(s, api->nexthop_num + api->ifindex_num); + stream_putc(s, api->nexthop_num + api->ifindex_num); for (i = 0; i < api->nexthop_num; i++) { stream_putc(s, NEXTHOP_TYPE_IPV4); @@ -769,13 +761,7 @@ int zapi_ipv4_route_ipv6_nexthop(u_char cmd, struct zclient *zclient, /* Nexthop, ifindex, distance and metric information. */ if (CHECK_FLAG(api->message, ZAPI_MESSAGE_NEXTHOP)) { - if (CHECK_FLAG(api->flags, ZEBRA_FLAG_BLACKHOLE)) { - stream_putc(s, 1); - stream_putc(s, NEXTHOP_TYPE_BLACKHOLE); - /* XXX assert(api->nexthop_num == 0); */ - /* XXX assert(api->ifindex_num == 0); */ - } else - stream_putc(s, api->nexthop_num + api->ifindex_num); + stream_putc(s, api->nexthop_num + api->ifindex_num); for (i = 0; i < api->nexthop_num; i++) { stream_putc(s, NEXTHOP_TYPE_IPV6); @@ -855,13 +841,7 @@ int zapi_ipv6_route(u_char cmd, struct zclient *zclient, struct prefix_ipv6 *p, /* Nexthop, ifindex, distance and metric information. */ if (CHECK_FLAG(api->message, ZAPI_MESSAGE_NEXTHOP)) { - if (CHECK_FLAG(api->flags, ZEBRA_FLAG_BLACKHOLE)) { - stream_putc(s, 1); - stream_putc(s, NEXTHOP_TYPE_BLACKHOLE); - /* XXX assert(api->nexthop_num == 0); */ - /* XXX assert(api->ifindex_num == 0); */ - } else - stream_putc(s, api->nexthop_num + api->ifindex_num); + stream_putc(s, api->nexthop_num + api->ifindex_num); for (i = 0; i < api->nexthop_num; i++) { stream_putc(s, NEXTHOP_TYPE_IPV6); diff --git a/lib/zclient.h b/lib/zclient.h index 7c4780201e..e05e9d8ad9 100644 --- a/lib/zclient.h +++ b/lib/zclient.h @@ -222,7 +222,10 @@ struct zserv_header { struct zapi_nexthop { enum nexthop_types_t type; ifindex_t ifindex; - union g_addr gate; + union { + union g_addr gate; + enum blackhole_type bh_type; + }; /* MPLS labels for BGP-LU or Segment Routing */ uint8_t label_num; @@ -429,4 +432,14 @@ extern int zclient_route_send(u_char, struct zclient *, struct zapi_route *); extern int zapi_route_encode(u_char, struct stream *, struct zapi_route *); extern int zapi_route_decode(struct stream *, struct zapi_route *); +static inline void zapi_route_set_blackhole(struct zapi_route *api, + enum blackhole_type bh_type) +{ + api->nexthop_num = 1; + api->nexthops[0].type = NEXTHOP_TYPE_BLACKHOLE; + api->nexthops[0].bh_type = bh_type; + SET_FLAG(api->message, ZAPI_MESSAGE_NEXTHOP); +}; + + #endif /* _ZEBRA_ZCLIENT_H */ diff --git a/nhrpd/nhrp_route.c b/nhrpd/nhrp_route.c index 4b86bca5f7..495e226f15 100644 --- a/nhrpd/nhrp_route.c +++ b/nhrpd/nhrp_route.c @@ -99,7 +99,9 @@ void nhrp_route_announce(int add, enum nhrp_cache_type type, const struct prefix switch (type) { case NHRP_CACHE_NEGATIVE: - SET_FLAG(api.flags, ZEBRA_FLAG_REJECT); + zapi_route_set_blackhole(&api, BLACKHOLE_REJECT); + ifp = NULL; + nexthop = NULL; break; case NHRP_CACHE_DYNAMIC: case NHRP_CACHE_NHS: @@ -158,7 +160,7 @@ void nhrp_route_announce(int add, enum nhrp_cache_type type, const struct prefix " count %d dev %s", add ? "add" : "del", buf[0], nexthop ? inet_ntop(api.prefix.family, &api_nh->gate, buf[1], sizeof(buf[1])) : "", - api.metric, api.nexthop_num, ifp->name); + api.metric, api.nexthop_num, ifp ? ifp->name : "none"); } zclient_route_send(add ? ZEBRA_ROUTE_ADD : ZEBRA_ROUTE_DELETE, zclient, diff --git a/ospf6d/ospf6_zebra.c b/ospf6d/ospf6_zebra.c index 3443bc47b6..ae08384559 100644 --- a/ospf6d/ospf6_zebra.c +++ b/ospf6d/ospf6_zebra.c @@ -392,9 +392,9 @@ void ospf6_zebra_add_discard(struct ospf6_route *request) memset(&api, 0, sizeof(api)); api.vrf_id = VRF_DEFAULT; api.type = ZEBRA_ROUTE_OSPF6; - api.flags = ZEBRA_FLAG_BLACKHOLE; api.safi = SAFI_UNICAST; api.prefix = *dest; + zapi_route_set_blackhole(&api, BLACKHOLE_NULL); zclient_route_send(ZEBRA_ROUTE_ADD, zclient, &api); @@ -425,9 +425,9 @@ void ospf6_zebra_delete_discard(struct ospf6_route *request) memset(&api, 0, sizeof(api)); api.vrf_id = VRF_DEFAULT; api.type = ZEBRA_ROUTE_OSPF6; - api.flags = ZEBRA_FLAG_BLACKHOLE; api.safi = SAFI_UNICAST; api.prefix = *dest; + zapi_route_set_blackhole(&api, BLACKHOLE_NULL); zclient_route_send(ZEBRA_ROUTE_DELETE, zclient, &api); diff --git a/ospfd/ospf_zebra.c b/ospfd/ospf_zebra.c index dcb392f1ad..e26a33c35f 100644 --- a/ospfd/ospf_zebra.c +++ b/ospfd/ospf_zebra.c @@ -442,9 +442,9 @@ void ospf_zebra_add_discard(struct prefix_ipv4 *p) api.vrf_id = VRF_DEFAULT; api.type = ZEBRA_ROUTE_OSPF; api.instance = ospf->instance; - api.flags = ZEBRA_FLAG_BLACKHOLE; api.safi = SAFI_UNICAST; memcpy(&api.prefix, p, sizeof(*p)); + zapi_route_set_blackhole(&api, BLACKHOLE_NULL); zclient_route_send(ZEBRA_ROUTE_ADD, zclient, &api); @@ -462,9 +462,9 @@ void ospf_zebra_delete_discard(struct prefix_ipv4 *p) api.vrf_id = VRF_DEFAULT; api.type = ZEBRA_ROUTE_OSPF; api.instance = ospf->instance; - api.flags = ZEBRA_FLAG_BLACKHOLE; api.safi = SAFI_UNICAST; memcpy(&api.prefix, p, sizeof(*p)); + zapi_route_set_blackhole(&api, BLACKHOLE_NULL); zclient_route_send(ZEBRA_ROUTE_DELETE, zclient, &api); @@ -900,17 +900,10 @@ static int ospf_zebra_read_route(int command, struct zclient *zclient, if (command == ZEBRA_REDISTRIBUTE_ROUTE_ADD) { /* XXX|HACK|TODO|FIXME: - * Maybe we should ignore reject/blackhole routes? Testing shows - * that - * there is no problems though and this is only way to - * "summarize" - * routes in ASBR at the moment. Maybe we need just a better - * generalised - * solution for these types? - * - * if ( CHECK_FLAG (api.flags, ZEBRA_FLAG_BLACKHOLE) - * || CHECK_FLAG (api.flags, ZEBRA_FLAG_REJECT)) - * return 0; + * Maybe we should ignore reject/blackhole routes? Testing + * shows that there is no problems though and this is only way + * to "summarize" routes in ASBR at the moment. Maybe we need + * just a better generalised solution for these types? */ /* Protocol tag overwrites all other tag value sent by zebra */