diff --git a/nest/route.h b/nest/route.h index 28980c7c..8fe64a83 100644 --- a/nest/route.h +++ b/nest/route.h @@ -222,13 +222,6 @@ typedef struct rte { byte pflags; /* Protocol-specific flags */ btime lastmod; /* Last modified */ union { /* Protocol-dependent data (metrics etc.) */ - 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; } rte; diff --git a/sysdep/bsd/krt-sock.c b/sysdep/bsd/krt-sock.c index b55df047..bca2d9d2 100644 --- a/sysdep/bsd/krt-sock.c +++ b/sysdep/bsd/krt-sock.c @@ -551,13 +551,21 @@ krt_read_route(struct ks_msg *msg, struct krt_proto *p, int scan) rte e0 = {}, *e = &e0; e->attrs = &a; e->net = net; - e->u.krt.src = src; - e->u.krt.proto = src2; + + ea_list *ea = alloca(sizeof(ea_list) + 1 * sizeof(eattr)); + *ea = (ea_list) { .count = 1, .next = e->attrs->eattrs }; + e->attrs->eattrs = ea; + + ea->attrs[0] = (eattr) { + .id = EA_KRT_SOURCE, + .type = EAF_TYPE_INT, + .u.data = src2, + }; if (scan) - krt_got_route(p, e); + krt_got_route(p, e, src); else - krt_got_route_async(p, e, new); + krt_got_route_async(p, e, new, src); } static void diff --git a/sysdep/linux/netlink.c b/sysdep/linux/netlink.c index c8eeda7d..ae33a144 100644 --- a/sysdep/linux/netlink.c +++ b/sysdep/linux/netlink.c @@ -1456,14 +1456,26 @@ nl_announce_route(struct nl_parse_state *s) rte e0 = {}, *e = &e0; e->attrs = s->attrs; e->net = s->net; - e->u.krt.src = s->krt_src; - e->u.krt.proto = s->krt_proto; - e->u.krt.metric = s->krt_metric; + + ea_list *ea = alloca(sizeof(ea_list) + 2 * sizeof(eattr)); + *ea = (ea_list) { .count = 2, .next = e->attrs->eattrs }; + e->attrs->eattrs = ea; + + 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) - krt_got_route(s->proto, e); + krt_got_route(s->proto, e, s->krt_src); 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->attrs = NULL; diff --git a/sysdep/unix/krt.c b/sysdep/unix/krt.c index 0617ba43..995b65ed 100644 --- a/sysdep/unix/krt.c +++ b/sysdep/unix/krt.c @@ -277,22 +277,23 @@ static struct tbf rl_alien = TBF_DEFAULT_LOG_LIMITS; * 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 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 krt_uptodate(rte *a, rte *b) { - if (a->attrs != b->attrs) - return 0; - - if (a->u.krt.proto != b->u.krt.proto) - return 0; - - return 1; + return (a->attrs == b->attrs); } static void @@ -300,8 +301,6 @@ krt_learn_announce_update(struct krt_proto *p, rte *e) { rte e0 = { .attrs = rta_clone(e->attrs), - .pflags = EA_ID_FLAG(EA_KRT_SOURCE) | EA_ID_FLAG(EA_KRT_METRIC), - .u.krt = e->u.krt, }; rte_update(p->p.main_channel, e->net->n.addr, &e0); @@ -332,7 +331,7 @@ krt_learn_scan(struct krt_proto *p, rte *e) { krt_trace_in_rl(&rl_alien, p, e, "[alien] seen"); rte_free(e); - m->u.krt.seen = 1; + m->pflags |= KRT_REF_SEEN; } else { @@ -348,7 +347,7 @@ krt_learn_scan(struct krt_proto *p, rte *e) { e->next = n->routes; n->routes = e; - e->u.krt.seen = 1; + e->pflags |= KRT_REF_SEEN; } } @@ -378,24 +377,23 @@ again: ee = &n->routes; while (e = *ee) { - if (e->u.krt.best) + if (e->pflags & KRT_REF_BEST) old_best = e; - if (!e->u.krt.seen) + if (!(e->pflags & KRT_REF_SEEN)) { *ee = e->next; rte_free(e); continue; } - if (!best || best->u.krt.metric > e->u.krt.metric) + if (!best || krt_metric(best) > krt_metric(e)) { best = e; pbest = ee; } - e->u.krt.seen = 0; - e->u.krt.best = 0; + e->pflags &= ~(KRT_REF_SEEN | KRT_REF_BEST); ee = &e->next; } if (!n->routes) @@ -409,18 +407,18 @@ again: goto again; } - best->u.krt.best = 1; + best->pflags |= KRT_REF_BEST; *pbest = best->next; best->next = n->routes; n->routes = best; 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); } 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; @@ -480,18 +478,18 @@ krt_learn_async(struct krt_proto *p, rte *e, int new) bestp = &n->routes; 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; bestp = gg; } - g->u.krt.best = 0; + g->pflags &= ~KRT_REF_BEST; } if (best) { - best->u.krt.best = 1; + best->pflags |= KRT_REF_BEST; *bestp = best->next; best->next = n->routes; n->routes = best; @@ -531,12 +529,6 @@ krt_dump(struct proto *P) 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 /* @@ -627,13 +619,13 @@ krt_same_dest(rte *k, rte *e) */ 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; net *n = e->net; #ifdef KRT_ALLOW_LEARN - switch (e->u.krt.src) + switch (src) { case KRT_SRC_KERNEL: goto ignore; @@ -750,11 +742,11 @@ krt_prune(struct krt_proto *p) } 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; - switch (e->u.krt.src) + switch (src) { case KRT_SRC_BIRD: /* Should be filtered by the back end */ @@ -883,22 +875,6 @@ krt_scan_timer_kick(struct krt_proto *p) * 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 krt_preexport(struct proto *P, rte **new, struct linpool *pool UNUSED) { @@ -980,14 +956,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 */ @@ -1042,9 +1010,6 @@ krt_init(struct proto_config *CF) p->p.if_notify = krt_if_notify; p->p.reload_routes = krt_reload_routes; 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); return &p->p; @@ -1202,6 +1167,5 @@ struct protocol proto_unix_kernel = { .get_attr = krt_get_attr, #ifdef KRT_ALLOW_LEARN .dump = krt_dump, - .dump_attrs = krt_dump_attrs, #endif }; diff --git a/sysdep/unix/krt.h b/sysdep/unix/krt.h index 4a5d10d2..310a2d11 100644 --- a/sysdep/unix/krt.h +++ b/sysdep/unix/krt.h @@ -24,6 +24,9 @@ struct kif_proto; #define EA_KRT_SOURCE EA_CODE(PROTOCOL_KERNEL, 0) #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 */ #ifdef CONFIG_SELF_CONSCIOUS @@ -76,8 +79,8 @@ extern pool *krt_pool; struct proto_config * kif_init_config(int class); void kif_request_scan(void); -void krt_got_route(struct krt_proto *p, struct rte *e); -void krt_got_route_async(struct krt_proto *p, struct rte *e, int new); +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, s8 src); static inline int krt_get_sync_error(struct krt_proto *p, struct rte *e)