diff --git a/nest/route.h b/nest/route.h index c7c44ecc..2256b671 100644 --- a/nest/route.h +++ b/nest/route.h @@ -270,8 +270,10 @@ typedef struct rte { #define REF_STALE 4 /* Route is stale in a refresh cycle */ #define REF_DISCARD 8 /* Route is scheduled for discard */ +static inline int rte_is_resolvable(rte *r); + /* Route is valid for propagation (may depend on other flags in the future), accepts NULL */ -static inline int rte_is_valid(rte *r) { return r && !(r->flags & REF_FILTERED); } +static inline int rte_is_valid(rte *r) { return r && !(r->flags & REF_FILTERED) && rte_is_resolvable(r); } /* Route just has REF_FILTERED flag */ static inline int rte_is_filtered(rte *r) { return !!(r->flags & REF_FILTERED); } @@ -451,7 +453,8 @@ typedef struct rta { #define RTD_BLACKHOLE 2 /* Silently drop packets */ #define RTD_UNREACHABLE 3 /* Reject as unreachable */ #define RTD_PROHIBIT 4 /* Administratively prohibited */ -#define RTD_MAX 5 +#define RTD_UNRESOLVABLE 5 /* Recursive route is unresolvable */ +#define RTD_MAX 6 /* Flags for net->n.flags, used by kernel syncer */ #define KRF_INSTALLED 0x80 /* This route should be installed in the kernel */ @@ -472,6 +475,9 @@ static inline const char *rta_dest_name(uint n) static inline int rte_is_reachable(rte *r) { return r->attrs->dest == RTD_UNICAST; } +static inline int rte_is_resolvable(rte *r) +{ return r->attrs->dest != RTD_UNRESOLVABLE; } + /* * Extended Route Attributes diff --git a/nest/rt-attr.c b/nest/rt-attr.c index d0d11617..3cbd25b0 100644 --- a/nest/rt-attr.c +++ b/nest/rt-attr.c @@ -64,6 +64,7 @@ const char * rta_dest_names[RTD_MAX] = { [RTD_BLACKHOLE] = "blackhole", [RTD_UNREACHABLE] = "unreachable", [RTD_PROHIBIT] = "prohibited", + [RTD_UNRESOLVABLE] = "unresolvable", }; pool *rta_pool; diff --git a/nest/rt-show.c b/nest/rt-show.c index 1f1b73d2..f3706d78 100644 --- a/nest/rt-show.c +++ b/nest/rt-show.c @@ -34,7 +34,7 @@ rt_show_rte(struct cli *c, byte *ia, rte *e, struct rt_show_data *d, ea_list *tm byte from[IPA_MAX_TEXT_LENGTH+8]; byte tm[TM_DATETIME_BUFFER_SIZE], info[256]; rta *a = e->attrs; - int primary = (e->net->routes == e); + int primary = (e->net->routes == e) && rte_is_valid(e); int sync_error = (e->net->n.flags & KRF_SYNC_ERROR); void (*get_route_info)(struct rte *, byte *buf, struct ea_list *attrs); struct nexthop *nh; @@ -139,6 +139,9 @@ rt_show_net(struct cli *c, net *n, struct rt_show_data *d) } else if (d->export_mode) { + if (!rte_is_valid(e)) + goto skip; + struct proto *ep = ec->proto; int ic = ep->import_control ? ep->import_control(ep, &e, &tmpa, c->show_pool) : 0; diff --git a/nest/rt-table.c b/nest/rt-table.c index efc1f1d7..03d63154 100644 --- a/nest/rt-table.c +++ b/nest/rt-table.c @@ -2609,7 +2609,7 @@ rt_update_hostentry(rtable *tab, struct hostentry *he) /* Reset the hostentry */ he->src = NULL; - he->dest = RTD_UNREACHABLE; + he->dest = RTD_UNRESOLVABLE; he->nexthop_linkable = 0; he->igp_metric = 0;