summaryrefslogtreecommitdiff
path: root/proto
diff options
context:
space:
mode:
Diffstat (limited to 'proto')
-rw-r--r--proto/babel/babel.c18
-rw-r--r--proto/bgp/attrs.c17
-rw-r--r--proto/bgp/bgp.h4
-rw-r--r--proto/bgp/packets.c25
-rw-r--r--proto/ospf/rt.c4
-rw-r--r--proto/ospf/topology.c11
-rw-r--r--proto/perf/perf.c4
-rw-r--r--proto/rip/rip.c4
-rw-r--r--proto/rpki/rpki.c4
-rw-r--r--proto/static/static.c6
10 files changed, 49 insertions, 48 deletions
diff --git a/proto/babel/babel.c b/proto/babel/babel.c
index 9a43f484..b90dcd3f 100644
--- a/proto/babel/babel.c
+++ b/proto/babel/babel.c
@@ -677,10 +677,7 @@ babel_announce_rte(struct babel_proto *p, struct babel_entry *e)
}
};
- rta a0 = {
- .dest = RTD_UNICAST,
- .eattrs = &eattrs.l,
- };
+ rta a0 = { .eattrs = &eattrs.l, };
rta *a = rta_lookup(&a0);
rte *rte = rte_get_temp(a, p->p.main_source);
@@ -691,12 +688,11 @@ babel_announce_rte(struct babel_proto *p, struct babel_entry *e)
else if (e->valid && (e->router_id != p->router_id))
{
/* Unreachable */
- rta a0 = {
- .dest = RTD_UNREACHABLE,
- };
+ rta a0 = {};
ea_set_attr_u32(&a0.eattrs, &ea_gen_preference, 0, 1);
ea_set_attr_u32(&a0.eattrs, &ea_gen_source, 0, RTS_BABEL);
+ ea_set_dest(&a0.eattrs, 0, RTD_UNREACHABLE);
rta *a = rta_lookup(&a0);
rte *rte = rte_get_temp(a, p->p.main_source);
@@ -2263,9 +2259,13 @@ babel_kick_timer(struct babel_proto *p)
static int
babel_preexport(struct proto *P, struct rte *new)
{
- struct rta *a = new->attrs;
+ if (new->src->proto != P)
+ return 0;
+
/* Reject our own unreachable routes */
- if ((a->dest == RTD_UNREACHABLE) && (new->src->proto == P))
+ eattr *ea = ea_find(new->attrs->eattrs, &ea_gen_nexthop);
+ struct nexthop_adata *nhad = (void *) ea->u.ptr;
+ if (!NEXTHOP_IS_REACHABLE(nhad))
return -1;
return 0;
diff --git a/proto/bgp/attrs.c b/proto/bgp/attrs.c
index 1efc26ce..6a9e4026 100644
--- a/proto/bgp/attrs.c
+++ b/proto/bgp/attrs.c
@@ -1711,9 +1711,20 @@ bgp_preexport(struct proto *P, rte *e)
if (src == NULL)
return 0;
- /* Reject flowspec that failed validation */
- if ((e->attrs->dest == RTD_UNREACHABLE) && net_is_flow(e->net->n.addr))
- return -1;
+ /* Reject flowspec that failed or are pending validation */
+ if (net_is_flow(e->net->n.addr))
+ switch (rt_get_flowspec_valid(e))
+ {
+ case FLOWSPEC_VALID:
+ break;
+ case FLOWSPEC_INVALID:
+ return -1;
+ case FLOWSPEC_UNKNOWN:
+ if ((rt_get_source_attr(e) == RTS_BGP) &&
+ ((struct bgp_channel *) e->sender)->base_table)
+ return -1;
+ break;
+ }
/* IBGP route reflection, RFC 4456 */
if (p->is_internal && src->is_internal && (p->local_as == src->local_as))
diff --git a/proto/bgp/bgp.h b/proto/bgp/bgp.h
index 6abb7870..2f98dc1b 100644
--- a/proto/bgp/bgp.h
+++ b/proto/bgp/bgp.h
@@ -519,7 +519,9 @@ struct rte_source *bgp_get_source(struct bgp_proto *p, u32 path_id);
static inline int
rte_resolvable(rte *rt)
{
- return rt->attrs->dest != RTD_UNREACHABLE;
+ eattr *nhea = ea_find(rt->attrs->eattrs, &ea_gen_nexthop);
+ struct nexthop_adata *nhad = (void *) nhea->u.ptr;
+ return NEXTHOP_IS_REACHABLE(nhad) || (nhad->dest != RTD_UNREACHABLE);
}
diff --git a/proto/bgp/packets.c b/proto/bgp/packets.c
index b07320aa..4c46c60e 100644
--- a/proto/bgp/packets.c
+++ b/proto/bgp/packets.c
@@ -968,7 +968,6 @@ bgp_apply_next_hop(struct bgp_parse_state *s, rta *a, ip_addr gw, ip_addr ll)
ea_set_attr_u32(&a->eattrs, &ea_gen_igp_metric, 0, c->cf->cost);
- a->dest = RTD_UNICAST;
struct nexthop_adata nhad = {
.nh = {
.gw = nbr->addr,
@@ -1003,8 +1002,7 @@ bgp_apply_mpls_labels(struct bgp_parse_state *s, rta *a, u32 lnum, u32 labels[ln
{
REPORT("Too many MPLS labels ($u)", lnum);
- a->dest = RTD_UNREACHABLE;
- ea_unset_attr(&a->eattrs, 0, &ea_gen_nexthop);
+ ea_set_dest(&a->eattrs, 0, RTD_UNREACHABLE);
return;
}
@@ -1039,15 +1037,21 @@ static void
bgp_apply_flow_validation(struct bgp_parse_state *s, const net_addr *n, rta *a)
{
struct bgp_channel *c = s->channel;
- int valid = rt_flowspec_check(c->base_table, c->c.table, n, a, s->proto->is_interior);
- a->dest = valid ? RTD_NONE : RTD_UNREACHABLE;
+ uint valid = rt_flowspec_check(c->base_table, c->c.table, n, a, s->proto->is_interior);
- /* Invalidate cached rta if dest changes */
- if (s->cached_rta && (s->cached_rta->dest != a->dest))
+ /* Invalidate cached rta */
+ if (s->cached_rta)
{
+ /* Has't changed */
+ if (valid == ea_get_int(s->cached_rta->eattrs, &ea_gen_flowspec_valid, FLOWSPEC_UNKNOWN))
+ return;
+
rta_free(s->cached_rta);
s->cached_rta = NULL;
}
+
+ /* Set the value */
+ ea_set_attr_u32(&a->eattrs, &ea_gen_flowspec_valid, 0, valid);
}
static int
@@ -1107,17 +1111,14 @@ bgp_use_gateway(struct bgp_export_state *s)
if (c->cf->next_hop_self && bgp_match_src(s, c->cf->next_hop_self))
return NULL;
- /* Unreachable */
- if (ra->dest != RTD_UNICAST)
- return NULL;
-
eattr *nhea = ea_find(ra->eattrs, &ea_gen_nexthop);
if (!nhea)
return NULL;
/* We need one valid global gateway */
struct nexthop_adata *nhad = (struct nexthop_adata *) nhea->u.ptr;
- if (!NEXTHOP_ONE(nhad) || ipa_zero(nhad->nh.gw) ||
+ if (!NEXTHOP_IS_REACHABLE(nhad) ||
+ !NEXTHOP_ONE(nhad) || ipa_zero(nhad->nh.gw) ||
ipa_is_link_local(nhad->nh.gw))
return NULL;
diff --git a/proto/ospf/rt.c b/proto/ospf/rt.c
index 6070fd34..afe4a01f 100644
--- a/proto/ospf/rt.c
+++ b/proto/ospf/rt.c
@@ -1983,8 +1983,7 @@ ort_changed(ort *nf, rta *nr)
if (!or ||
(nf->n.metric1 != nf->old_metric1) || (nf->n.metric2 != nf->old_metric2) ||
- (nf->n.tag != nf->old_tag) || (nf->n.rid != nf->old_rid) ||
- (nr->dest != or->dest))
+ (nf->n.tag != nf->old_tag) || (nf->n.rid != nf->old_rid))
return 1;
eattr *nhea_n = ea_find(nr->eattrs, &ea_gen_nexthop);
@@ -2049,7 +2048,6 @@ again1:
if (nf->n.type) /* Add the route */
{
rta a0 = {
- .dest = RTD_UNICAST,
};
struct {
diff --git a/proto/ospf/topology.c b/proto/ospf/topology.c
index ca4620cc..09ec9f28 100644
--- a/proto/ospf/topology.c
+++ b/proto/ospf/topology.c
@@ -1366,16 +1366,9 @@ ospf_rt_notify(struct proto *P, struct channel *ch UNUSED, net *n, rte *new, rte
uint tag = ea_get_int(a->eattrs, &ea_ospf_tag, 0);
ip_addr fwd = IPA_NONE;
- if (a->dest == RTD_UNICAST)
+ eattr *nhea = ea_find(a->eattrs, &ea_gen_nexthop);
+ if (nhea)
{
- eattr *nhea = ea_find(a->eattrs, &ea_gen_nexthop);
- if (!nhea)
- {
- log(L_ERR "%s: Unicast route without nexthop for %N",
- p->p.name, n->n.addr);
- return;
- }
-
struct nexthop_adata *nhad = (struct nexthop_adata *) nhea->u.ptr;
if (use_gw_for_fwaddr(p, nhad->nh.gw, nhad->nh.iface))
fwd = nhad->nh.gw;
diff --git a/proto/perf/perf.c b/proto/perf/perf.c
index 8642e0a1..d1ff6adf 100644
--- a/proto/perf/perf.c
+++ b/proto/perf/perf.c
@@ -142,9 +142,7 @@ perf_loop(void *data)
*((net_addr_ip4 *) &(p->data[i].net)) = random_net_ip4();
if (!p->attrs_per_rte || !(i % p->attrs_per_rte)) {
- struct rta a0 = {
- .dest = RTD_UNICAST,
- };
+ struct rta a0 = {};
ea_set_attr_u32(&a0.eattrs, &ea_gen_preference, 0, p->p.main_channel->preference);
ea_set_attr_u32(&a0.eattrs, &ea_gen_source, 0, RTS_PERF);
diff --git a/proto/rip/rip.c b/proto/rip/rip.c
index 425a411c..a0f2fdc0 100644
--- a/proto/rip/rip.c
+++ b/proto/rip/rip.c
@@ -151,9 +151,7 @@ rip_announce_rte(struct rip_proto *p, struct rip_entry *en)
if (rt)
{
/* Update */
- rta a0 = {
- .dest = RTD_UNICAST,
- };
+ rta a0 = {};
struct {
ea_list l;
diff --git a/proto/rpki/rpki.c b/proto/rpki/rpki.c
index 56d8add2..4318cbb7 100644
--- a/proto/rpki/rpki.c
+++ b/proto/rpki/rpki.c
@@ -120,9 +120,7 @@ rpki_table_add_roa(struct rpki_cache *cache, struct channel *channel, const net_
{
struct rpki_proto *p = cache->p;
- rta a0 = {
- .dest = RTD_NONE,
- };
+ rta a0 = {};
ea_set_attr_u32(&a0.eattrs, &ea_gen_preference, 0, channel->preference);
ea_set_attr_u32(&a0.eattrs, &ea_gen_source, 0, RTS_RPKI);
diff --git a/proto/static/static.c b/proto/static/static.c
index 5102617f..806849c4 100644
--- a/proto/static/static.c
+++ b/proto/static/static.c
@@ -55,7 +55,6 @@ static_announce_rte(struct static_proto *p, struct static_route *r)
{
rta *a = allocz(RTA_MAX_SIZE);
struct rte_src *src = static_get_source(p, r->index);
- a->dest = r->dest;
ea_set_attr_u32(&a->eattrs, &ea_gen_preference, 0, p->p.main_channel->preference);
ea_set_attr_u32(&a->eattrs, &ea_gen_source, 0, RTS_STATIC);
@@ -97,7 +96,7 @@ static_announce_rte(struct static_proto *p, struct static_route *r)
nhad->ad.data, (void *) nh - (void *) nhad->ad.data);
}
- if (r->dest == RTDX_RECURSIVE)
+ else if (r->dest == RTDX_RECURSIVE)
{
rtable *tab = ipa_is_ip4(r->via) ? p->igp_table_ip4 : p->igp_table_ip6;
u32 *labels = r->mls ? (void *) r->mls->data : NULL;
@@ -107,6 +106,9 @@ static_announce_rte(struct static_proto *p, struct static_route *r)
r->via, IPA_NONE, lnum, labels);
}
+ else if (r->dest)
+ ea_set_dest(&a->eattrs, 0, r->dest);
+
/* Already announced */
if (r->state == SRS_CLEAN)
return;