Kernel: Convert the rte-local attributes to extended attributes and flags to pflags

This commit is contained in:
Maria Matejka 2020-02-13 16:59:53 +01:00
parent 3660f19dd5
commit e42eedb912
5 changed files with 61 additions and 84 deletions

View file

@ -250,13 +250,6 @@ typedef struct rte {
s8 stale; /* Route is LLGR_STALE, -1 if unknown */ s8 stale; /* Route is LLGR_STALE, -1 if unknown */
} bgp; } bgp;
#endif #endif
struct { /* Routes generated by krt sync (both temporary and inherited ones) */
s8 src; /* Alleged route source (see krt.h) */
u8 proto; /* Kernel source protocol ID */
u8 seen; /* Seen during last scan */
u8 best; /* Best route in network, propagated to core */
u32 metric; /* Kernel metric */
} krt;
} u; } u;
} rte; } rte;

View file

@ -552,16 +552,21 @@ krt_read_route(struct ks_msg *msg, struct krt_proto *p, int scan)
done: done:
e = rte_get_temp(&a); e = rte_get_temp(&a);
e->net = net; e->net = net;
e->u.krt.src = src;
e->u.krt.proto = src2; ea_list *ea = alloca(sizeof(ea_list) + 1 * sizeof(eattr));
e->u.krt.seen = 0; *ea = (ea_list) { .count = 1, .next = e->attrs->eattrs };
e->u.krt.best = 0; e->attrs->eattrs = ea;
e->u.krt.metric = 0;
ea->attrs[0] = (eattr) {
.id = EA_KRT_SOURCE,
.type = EAF_TYPE_INT,
.u.data = src2,
};
if (scan) if (scan)
krt_got_route(p, e); krt_got_route(p, e, src);
else else
krt_got_route_async(p, e, new); krt_got_route_async(p, e, new, src);
} }
static void static void

View file

@ -1488,16 +1488,26 @@ nl_announce_route(struct nl_parse_state *s)
{ {
rte *e = rte_get_temp(s->attrs, s->proto->p.main_source); rte *e = rte_get_temp(s->attrs, s->proto->p.main_source);
e->net = s->net; e->net = s->net;
e->u.krt.src = s->krt_src;
e->u.krt.proto = s->krt_proto; ea_list *ea = alloca(sizeof(ea_list) + 2 * sizeof(eattr));
e->u.krt.seen = 0; *ea = (ea_list) { .count = 2, .next = e->attrs->eattrs };
e->u.krt.best = 0; e->attrs->eattrs = ea;
e->u.krt.metric = s->krt_metric;
ea->attrs[0] = (eattr) {
.id = EA_KRT_SOURCE,
.type = EAF_TYPE_INT,
.u.data = s->krt_proto,
};
ea->attrs[1] = (eattr) {
.id = EA_KRT_METRIC,
.type = EAF_TYPE_INT,
.u.data = s->krt_metric,
};
if (s->scan) if (s->scan)
krt_got_route(s->proto, e); krt_got_route(s->proto, e, s->krt_src);
else else
krt_got_route_async(s->proto, e, s->new); krt_got_route_async(s->proto, e, s->new, s->krt_src);
s->net = NULL; s->net = NULL;
s->attrs = NULL; s->attrs = NULL;

View file

@ -277,22 +277,23 @@ static struct tbf rl_alien = TBF_DEFAULT_LOG_LIMITS;
* the same key. * the same key.
*/ */
static inline u32
krt_metric(rte *a)
{
eattr *ea = ea_find(a->attrs->eattrs, EA_KRT_METRIC);
return ea ? ea->u.data : 0;
}
static inline int static inline int
krt_same_key(rte *a, rte *b) krt_same_key(rte *a, rte *b)
{ {
return a->u.krt.metric == b->u.krt.metric; return (krt_metric(a) == krt_metric(b));
} }
static inline int static inline int
krt_uptodate(rte *a, rte *b) krt_uptodate(rte *a, rte *b)
{ {
if (a->attrs != b->attrs) return (a->attrs == b->attrs);
return 0;
if (a->u.krt.proto != b->u.krt.proto)
return 0;
return 1;
} }
static void static void
@ -301,8 +302,6 @@ krt_learn_announce_update(struct krt_proto *p, rte *e)
net *n = e->net; net *n = e->net;
rta *aa = rta_clone(e->attrs); rta *aa = rta_clone(e->attrs);
rte *ee = rte_get_temp(aa, p->p.main_source); rte *ee = rte_get_temp(aa, p->p.main_source);
ee->pflags = EA_ID_FLAG(EA_KRT_SOURCE) | EA_ID_FLAG(EA_KRT_METRIC);
ee->u.krt = e->u.krt;
rte_update(&p->p, n->n.addr, ee); rte_update(&p->p, n->n.addr, ee);
} }
@ -331,7 +330,7 @@ krt_learn_scan(struct krt_proto *p, rte *e)
{ {
krt_trace_in_rl(&rl_alien, p, e, "[alien] seen"); krt_trace_in_rl(&rl_alien, p, e, "[alien] seen");
rte_free(e); rte_free(e);
m->u.krt.seen = 1; m->pflags |= KRT_REF_SEEN;
} }
else else
{ {
@ -347,7 +346,7 @@ krt_learn_scan(struct krt_proto *p, rte *e)
{ {
e->next = n->routes; e->next = n->routes;
n->routes = e; n->routes = e;
e->u.krt.seen = 1; e->pflags |= KRT_REF_SEEN;
} }
} }
@ -377,24 +376,23 @@ again:
ee = &n->routes; ee = &n->routes;
while (e = *ee) while (e = *ee)
{ {
if (e->u.krt.best) if (e->pflags & KRT_REF_BEST)
old_best = e; old_best = e;
if (!e->u.krt.seen) if (!(e->pflags & KRT_REF_SEEN))
{ {
*ee = e->next; *ee = e->next;
rte_free(e); rte_free(e);
continue; continue;
} }
if (!best || best->u.krt.metric > e->u.krt.metric) if (!best || krt_metric(best) > krt_metric(e))
{ {
best = e; best = e;
pbest = ee; pbest = ee;
} }
e->u.krt.seen = 0; e->pflags &= ~(KRT_REF_SEEN | KRT_REF_BEST);
e->u.krt.best = 0;
ee = &e->next; ee = &e->next;
} }
if (!n->routes) if (!n->routes)
@ -408,18 +406,18 @@ again:
goto again; goto again;
} }
best->u.krt.best = 1; best->pflags |= KRT_REF_BEST;
*pbest = best->next; *pbest = best->next;
best->next = n->routes; best->next = n->routes;
n->routes = best; n->routes = best;
if ((best != old_best) || p->reload) if ((best != old_best) || p->reload)
{ {
DBG("%I/%d: announcing (metric=%d)\n", n->n.prefix, n->n.pxlen, best->u.krt.metric); DBG("%I/%d: announcing (metric=%d)\n", n->n.prefix, n->n.pxlen, krt_metric(best));
krt_learn_announce_update(p, best); krt_learn_announce_update(p, best);
} }
else else
DBG("%I/%d: uptodate (metric=%d)\n", n->n.prefix, n->n.pxlen, best->u.krt.metric); DBG("%I/%d: uptodate (metric=%d)\n", n->n.prefix, n->n.pxlen, krt_metric(best));
} }
FIB_ITERATE_END; FIB_ITERATE_END;
@ -479,18 +477,18 @@ krt_learn_async(struct krt_proto *p, rte *e, int new)
bestp = &n->routes; bestp = &n->routes;
for(gg=&n->routes; g=*gg; gg=&g->next) for(gg=&n->routes; g=*gg; gg=&g->next)
{ {
if (best->u.krt.metric > g->u.krt.metric) if (krt_metric(best) > krt_metric(g))
{ {
best = g; best = g;
bestp = gg; bestp = gg;
} }
g->u.krt.best = 0; g->pflags &= ~KRT_REF_BEST;
} }
if (best) if (best)
{ {
best->u.krt.best = 1; best->pflags |= KRT_REF_BEST;
*bestp = best->next; *bestp = best->next;
best->next = n->routes; best->next = n->routes;
n->routes = best; n->routes = best;
@ -531,12 +529,6 @@ krt_dump(struct proto *P)
rt_dump(p->krt_table); rt_dump(p->krt_table);
} }
static void
krt_dump_attrs(rte *e)
{
debug(" [m=%d,p=%d]", e->u.krt.metric, e->u.krt.proto);
}
#endif #endif
/* /*
@ -627,13 +619,14 @@ krt_same_dest(rte *k, rte *e)
*/ */
void void
krt_got_route(struct krt_proto *p, rte *e) krt_got_route(struct krt_proto *p, rte *e, s8 src)
{ {
rte *new = NULL, *rt_free = NULL; rte *new = NULL, *rt_free = NULL;
net *n = e->net; net *n = e->net;
e->pflags = 0;
#ifdef KRT_ALLOW_LEARN #ifdef KRT_ALLOW_LEARN
switch (e->u.krt.src) switch (src)
{ {
case KRT_SRC_KERNEL: case KRT_SRC_KERNEL:
goto ignore; goto ignore;
@ -755,11 +748,12 @@ krt_prune(struct krt_proto *p)
} }
void void
krt_got_route_async(struct krt_proto *p, rte *e, int new) krt_got_route_async(struct krt_proto *p, rte *e, int new, s8 src)
{ {
net *net = e->net; net *net = e->net;
e->pflags = 0;
switch (e->u.krt.src) switch (src)
{ {
case KRT_SRC_BIRD: case KRT_SRC_BIRD:
/* Should be filtered by the back end */ /* Should be filtered by the back end */
@ -889,22 +883,6 @@ krt_scan_timer_kick(struct krt_proto *p)
* Updates * Updates
*/ */
static void
krt_make_tmp_attrs(struct rte *rt, struct linpool *pool)
{
rte_init_tmp_attrs(rt, pool, 2);
rte_make_tmp_attr(rt, EA_KRT_SOURCE, EAF_TYPE_INT, rt->u.krt.proto);
rte_make_tmp_attr(rt, EA_KRT_METRIC, EAF_TYPE_INT, rt->u.krt.metric);
}
static void
krt_store_tmp_attrs(struct rte *rt, struct linpool *pool)
{
rte_init_tmp_attrs(rt, pool, 2);
rt->u.krt.proto = rte_store_tmp_attr(rt, EA_KRT_SOURCE);
rt->u.krt.metric = rte_store_tmp_attr(rt, EA_KRT_METRIC);
}
static int static int
krt_preexport(struct proto *P, rte *e) krt_preexport(struct proto *P, rte *e)
{ {
@ -984,14 +962,6 @@ krt_feed_end(struct channel *C)
} }
static int
krt_rte_same(rte *a, rte *b)
{
/* src is always KRT_SRC_ALIEN and type is irrelevant */
return (a->u.krt.proto == b->u.krt.proto) && (a->u.krt.metric == b->u.krt.metric);
}
/* /*
* Protocol glue * Protocol glue
*/ */
@ -1050,9 +1020,6 @@ krt_init(struct proto_config *CF)
p->p.if_notify = krt_if_notify; p->p.if_notify = krt_if_notify;
p->p.reload_routes = krt_reload_routes; p->p.reload_routes = krt_reload_routes;
p->p.feed_end = krt_feed_end; p->p.feed_end = krt_feed_end;
p->p.make_tmp_attrs = krt_make_tmp_attrs;
p->p.store_tmp_attrs = krt_store_tmp_attrs;
p->p.rte_same = krt_rte_same;
krt_sys_init(p); krt_sys_init(p);
return &p->p; return &p->p;
@ -1210,6 +1177,5 @@ struct protocol proto_unix_kernel = {
.get_attr = krt_get_attr, .get_attr = krt_get_attr,
#ifdef KRT_ALLOW_LEARN #ifdef KRT_ALLOW_LEARN
.dump = krt_dump, .dump = krt_dump,
.dump_attrs = krt_dump_attrs,
#endif #endif
}; };

View file

@ -24,6 +24,9 @@ struct kif_proto;
#define EA_KRT_SOURCE EA_CODE(PROTOCOL_KERNEL, 0) #define EA_KRT_SOURCE EA_CODE(PROTOCOL_KERNEL, 0)
#define EA_KRT_METRIC EA_CODE(PROTOCOL_KERNEL, 1) #define EA_KRT_METRIC EA_CODE(PROTOCOL_KERNEL, 1)
#define KRT_REF_SEEN 0x1 /* Seen in table */
#define KRT_REF_BEST 0x2 /* Best in table */
/* Whenever we recognize our own routes, we allow learing of foreign routes */ /* Whenever we recognize our own routes, we allow learing of foreign routes */
#ifdef CONFIG_SELF_CONSCIOUS #ifdef CONFIG_SELF_CONSCIOUS
@ -76,8 +79,8 @@ extern pool *krt_pool;
struct proto_config * kif_init_config(int class); struct proto_config * kif_init_config(int class);
void kif_request_scan(void); void kif_request_scan(void);
void krt_got_route(struct krt_proto *p, struct rte *e); void krt_got_route(struct krt_proto *p, struct rte *e, s8 src);
void krt_got_route_async(struct krt_proto *p, struct rte *e, int new); void krt_got_route_async(struct krt_proto *p, struct rte *e, int new, s8 src);
static inline int static inline int
krt_get_sync_error(struct krt_proto *p, struct rte *e) krt_get_sync_error(struct krt_proto *p, struct rte *e)