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;
* 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) {
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);
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;
* | 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
/* 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);
/* 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);
/* 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);
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;
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 */
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:
" count %d dev %s",
add ? "add" : "del", buf[0],
nexthop ? inet_ntop(api.prefix.family, &api_nh->gate, buf[1], sizeof(buf[1])) : "<onlink>",
- 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,
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);
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);
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);
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);
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 */