ea_set_attr_data(ea_list **to, const struct ea_class *def, uint flags, void *data, uint len)
{ ea_set_attr(to, EA_LITERAL_STORE_ADATA(def, flags, data, len)); }
-u32 rt_get_igp_metric(rte *rt);
+ /*
+ * Common route attributes
+ */
+
+ /* Preference: first-order comparison */
+ extern struct ea_class ea_gen_preference;
+ static inline u32 rt_get_preference(rte *rt)
+ { return ea_get_int(rt->attrs->eattrs, &ea_gen_preference, 0); }
+
+ /* IGP metric: second-order comparison */
+ extern struct ea_class ea_gen_igp_metric;
++u32 rt_get_igp_metric(const rte *rt);
+ #define IGP_METRIC_UNKNOWN 0x80000000 /* Default igp_metric used when no other
+ protocol-specific metric is availabe */
+
+
+ /* Next hop structures */
#define NEXTHOP_MAX_SIZE (sizeof(struct nexthop) + sizeof(u32)*MPLS_MAX_LABEL_STACK)
.nh.iface = ad->iface,
};
- a = rta_lookup(&a0);
- e = rte_get_temp(a, src);
- e->pflags = 0;
- rte_update2(c, net, e, src);
+ ea_set_attr_u32(&a0.eattrs, &ea_gen_preference, 0, c->preference);
+
+ rte e0 = {
+ .attrs = rta_lookup(&a0),
+ .src = src,
+ };
+
+ rte_update(c, net, &e0, src);
}
}
.source = RTS_BABEL,
.scope = SCOPE_UNIVERSE,
.dest = RTD_UNREACHABLE,
- .pref = 1,
};
- rta *a = rta_lookup(&a0);
- rte *rte = rte_get_temp(a, p->p.main_source);
- rte->pflags = 0;
+ ea_set_attr_u32(&a0.eattrs, &ea_gen_preference, 0, 1);
+
+ 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
{
int
bgp_rte_recalculate(rtable *table, net *net, rte *new, rte *old, rte *old_best)
{
- rte *r, *s;
rte *key = new ? new : old;
- u32 lpref = key->attrs->pref;
+ u32 lpref = rt_get_preference(key);
u32 lasn = bgp_get_neighbor(key);
int old_suppressed = old ? !!(old->pflags & BGP_REF_SUPPRESSED) : 0;
.dest = RTD_NONE,
};
- rta *a = rta_lookup(&a0);
- rte *e = rte_get_temp(a, p->p.main_source);
+ ea_set_attr_u32(&a0.eattrs, &ea_gen_preference, 0, channel->preference);
+
+ 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
static void
krt_learn_async(struct krt_proto *p, rte *e, int new)
{
- net *n0 = e->net;
- net *n = net_get(p->krt_table, n0->n.addr);
- rte *g, **gg, *best, **bestp, *old_best;
+ net *n = net_get(p->krt_table, e->net);
+ struct rte_storage *g, **gg, *best, **bestp, *old_best;
ASSERT(!e->attrs->cached);
- e->attrs->pref = p->p.main_channel->preference;
+ ea_set_attr_u32(&e->attrs->eattrs, &ea_gen_preference, 0, p->p.main_channel->preference);
- e->attrs = rta_lookup(e->attrs);
+ struct rte_storage *ee = rte_store(e, n, p->krt_table);
old_best = n->routes;
for(gg=&n->routes; g = *gg; gg = &g->next)