switch (sa.sa_code)
{
case SA_GW: RESULT(sa.type, ip, rta->nh.gw); break;
- case SA_NET: RESULT(sa.type, net, (*fs->rte)->net->n.addr); break;
- case SA_PROTO: RESULT(sa.type, s, (*fs->rte)->src->proto->name); break;
+ case SA_NET: RESULT(sa.type, net, fs->rte->net); break;
+ case SA_PROTO: RESULT(sa.type, s, fs->rte->src->proto->name); break;
- case SA_SOURCE: RESULT(sa.type, i, rta->source); break;
case SA_DEST: RESULT(sa.type, i, rta->dest); break;
case SA_IFNAME: RESULT(sa.type, s, rta->nh.iface ? rta->nh.iface->name : ""); break;
case SA_IFINDEX: RESULT(sa.type, i, rta->nh.iface ? rta->nh.iface->index : 0); break;
/* From: Advertising router */
extern struct ea_class ea_gen_from;
-static inline u32 rt_get_source_attr(rte *rt)
+ /* Source: An old method to devise the route source protocol and kind.
+ * To be superseded in a near future by something more informative. */
+ extern struct ea_class ea_gen_source;
++static inline u32 rt_get_source_attr(const rte *rt)
+ { return ea_get_int(rt->attrs->eattrs, &ea_gen_source, 0); }
+
/* Next hop structures */
#define NEXTHOP_MAX_SIZE (sizeof(struct nexthop) + sizeof(u32)*MPLS_MAX_LABEL_STACK)
};
ea_set_attr_u32(&a0.eattrs, &ea_gen_preference, 0, c->preference);
+ ea_set_attr_u32(&a0.eattrs, &ea_gen_source, 0, RTS_DEVICE);
- a = rta_lookup(&a0);
- e = rte_get_temp(a, src);
- e->pflags = 0;
- rte_update2(c, net, e, src);
+ rte e0 = {
+ .attrs = rta_lookup(&a0),
+ .src = src,
+ };
+
+ rte_update(c, net, &e0, src);
}
}
if (!nc)
continue;
- rte *rc = nc->routes;
+ const rte *rc = &nc->routes->rte;
- if (rc->attrs->source != RTS_BGP)
+ if (rt_get_source_attr(rc) != RTS_BGP)
return 0;
if (rta_get_first_asn(rc->attrs) != asn_b)
#endif /* CONFIG_BGP */
-static rte *
-rt_flowspec_update_rte(rtable *tab, rte *r)
+static struct rte_storage *
+rt_flowspec_update_rte(rtable *tab, net *n, rte *r)
{
#ifdef CONFIG_BGP
- if (r->attrs->source != RTS_BGP)
+ if (rt_get_source_attr(r) != RTS_BGP)
return NULL;
struct bgp_channel *bc = (struct bgp_channel *) r->sender;
};
ea_set_attr_u32(&a0.eattrs, &ea_gen_preference, 0, 1);
+ ea_set_attr_u32(&a0.eattrs, &ea_gen_source, 0, RTS_BABEL);
- rta *a = rta_lookup(&a0);
- rte *rte = rte_get_temp(a, p->p.main_source);
- rte->pflags = 0;
+ rte e0 = {
+ .attrs = &a0,
+ .src = p->p.main_source,
+ };
e->unreachable = 1;
- rte_update2(c, e->n.addr, rte, p->p.main_source);
+ rte_update(c, e->n.addr, &e0, p->p.main_source);
}
else
{
}
static u32
-ospf_rte_igp_metric(struct rte *rt)
+ospf_rte_igp_metric(const rte *rt)
{
- if (rt->attrs->source == RTS_OSPF_EXT2)
+ if (rt_get_source_attr(rt) == RTS_OSPF_EXT2)
return IGP_METRIC_UNKNOWN;
return ea_get_int(rt->attrs->eattrs, &ea_ospf_metric1, LSINFINITY);
eattrs.a[eattrs.l.count++] =
EA_LITERAL_EMBEDDED(&ea_ospf_router_id, 0, nf->n.rid);
+ ASSERT_DIE(ARRAY_SIZE(eattrs.a) >= eattrs.l.count);
a0.eattrs = &eattrs.l;
- rta *a = rta_lookup(&a0);
- rte *e = rte_get_temp(a, p->p.main_source);
-
rta_free(nf->old_rta);
- nf->old_rta = rta_clone(a);
+ nf->old_rta = rta_lookup(&a0);
+
+ rte e0 = {
+ .attrs = nf->old_rta,
+ .src = p->p.main_source,
+ };
DBG("Mod rte type %d - %N via %I on iface %s, met %d\n",
a0.source, nf->fn.addr, a0.gw, a0.iface ? a0.iface->name : "(none)", nf->n.metric1);
};
ea_set_attr_u32(&a0.eattrs, &ea_gen_preference, 0, channel->preference);
+ ea_set_attr_u32(&a0.eattrs, &ea_gen_source, 0, RTS_RPKI);
- rta *a = rta_lookup(&a0);
- rte *e = rte_get_temp(a, p->p.main_source);
+ rte e0 = { .attrs = &a0, .src = p->p.main_source, };
- e->pflags = 0;
-
- rte_update2(channel, &pfxr->n, e, e->src);
+ rte_update(channel, &pfxr->n, &e0, p->p.main_source);
}
void
net = net_get(p->p.main_channel->table, &ndst);
rta a = {
- .source = RTS_INHERIT,
- .src = p->p.main_source,
};
+ ea_set_attr_u32(&a->eattrs, &ea_gen_source, 0, RTS_INHERIT);
+
/* reject/blackhole routes have also set RTF_GATEWAY,
we wil check them first. */