#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); }
#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 */
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
[RTD_BLACKHOLE] = "blackhole",
[RTD_UNREACHABLE] = "unreachable",
[RTD_PROHIBIT] = "prohibited",
+ [RTD_UNRESOLVABLE] = "unresolvable",
};
pool *rta_pool;
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;
}
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;
/* Reset the hostentry */
he->src = NULL;
- he->dest = RTD_UNREACHABLE;
+ he->dest = RTD_UNRESOLVABLE;
he->nexthop_linkable = 0;
he->igp_metric = 0;