diff options
Diffstat (limited to 'nest')
-rw-r--r-- | nest/route.h | 4 | ||||
-rw-r--r-- | nest/rt-attr.c | 10 | ||||
-rw-r--r-- | nest/rt-dev.c | 3 | ||||
-rw-r--r-- | nest/rt-show.c | 6 | ||||
-rw-r--r-- | nest/rt-table.c | 51 |
5 files changed, 38 insertions, 36 deletions
diff --git a/nest/route.h b/nest/route.h index aec867e2..1dea058f 100644 --- a/nest/route.h +++ b/nest/route.h @@ -236,6 +236,7 @@ struct hostentry { typedef struct rte { struct rte *next; net *net; /* Network this RTE belongs to */ + struct rte_src *src; /* Route source that created the route */ struct channel *sender; /* Channel used to send the route to the routing table */ struct rta *attrs; /* Attributes of this route */ u32 id; /* Table specific route id */ @@ -326,7 +327,7 @@ static inline net *net_get(rtable *tab, const net_addr *addr) { return (net *) f void *net_route(rtable *tab, const net_addr *n); int net_roa_check(rtable *tab, const net_addr *n, u32 asn); rte *rte_find(net *net, struct rte_src *src); -rte *rte_get_temp(struct rta *); +rte *rte_get_temp(struct rta *, struct rte_src *src); void rte_update2(struct channel *c, const net_addr *n, rte *new, struct rte_src *src); /* rte_update() moved to protocol.h to avoid dependency conflicts */ int rt_examine(rtable *t, net_addr *a, struct proto *p, const struct filter *filter); @@ -441,7 +442,6 @@ typedef struct rta { u32 uc; /* Use count */ u32 hash_key; /* Hash over important fields */ struct ea_list *eattrs; /* Extended Attribute chain */ - struct rte_src *src; /* Route source that created the route */ struct hostentry *hostentry; /* Hostentry for recursive next-hops */ ip_addr from; /* Advertising router */ u32 igp_metric; /* IGP metric to next hop (for iBGP routes) */ diff --git a/nest/rt-attr.c b/nest/rt-attr.c index 4198b552..4057bf37 100644 --- a/nest/rt-attr.c +++ b/nest/rt-attr.c @@ -1105,7 +1105,6 @@ rta_hash(rta *a) mem_hash_init(&h); #define MIX(f) mem_hash_mix(&h, &(a->f), sizeof(a->f)); #define BMIX(f) mem_hash_mix_num(&h, a->f); - MIX(src); MIX(hostentry); MIX(from); MIX(igp_metric); @@ -1121,8 +1120,7 @@ rta_hash(rta *a) static inline int rta_same(rta *x, rta *y) { - return (x->src == y->src && - x->source == y->source && + return (x->source == y->source && x->scope == y->scope && x->dest == y->dest && x->igp_metric == y->igp_metric && @@ -1212,7 +1210,6 @@ rta_lookup(rta *o) r = rta_copy(o); r->hash_key = h; r->cached = 1; - rt_lock_source(r->src); rt_lock_hostentry(r->hostentry); rta_insert(r); @@ -1231,7 +1228,6 @@ rta__free(rta *a) if (a->next) a->next->pprev = a->pprev; rt_unlock_hostentry(a->hostentry); - rt_unlock_source(a->src); if (a->nh.next) nexthop_free(a->nh.next); ea_free(a->eattrs); @@ -1270,8 +1266,8 @@ rta_dump(rta *a) "RTS_OSPF_EXT2", "RTS_BGP", "RTS_PIPE", "RTS_BABEL" }; static char *rtd[] = { "", " DEV", " HOLE", " UNREACH", " PROHIBIT" }; - debug("p=%s pref=%d uc=%d %s %s%s h=%04x", - a->src->proto->name, a->pref, a->uc, rts[a->source], ip_scope_text(a->scope), + debug("pref=%d uc=%d %s %s%s h=%04x", + a->pref, a->uc, rts[a->source], ip_scope_text(a->scope), rtd[a->dest], a->hash_key); if (!a->cached) debug(" !CACHED"); diff --git a/nest/rt-dev.c b/nest/rt-dev.c index b8e945cf..e2e65926 100644 --- a/nest/rt-dev.c +++ b/nest/rt-dev.c @@ -83,7 +83,6 @@ dev_ifa_notify(struct proto *P, uint flags, struct ifa *ad) struct rte_src *src = rt_get_source(P, ad->iface->index); rta a0 = { - .src = src, .pref = c->preference, .source = RTS_DEVICE, .scope = SCOPE_UNIVERSE, @@ -92,7 +91,7 @@ dev_ifa_notify(struct proto *P, uint flags, struct ifa *ad) }; a = rta_lookup(&a0); - e = rte_get_temp(a); + e = rte_get_temp(a, src); e->pflags = 0; rte_update2(c, net, e, src); } diff --git a/nest/rt-show.c b/nest/rt-show.c index a0c675de..05065134 100644 --- a/nest/rt-show.c +++ b/nest/rt-show.c @@ -56,7 +56,7 @@ rt_show_rte(struct cli *c, byte *ia, rte *e, struct rt_show_data *d, int primary if (d->verbose && !rta_is_cached(a) && a->eattrs) ea_normalize(a->eattrs); - get_route_info = a->src->proto->proto->get_route_info; + get_route_info = e->src->proto->proto->get_route_info; if (get_route_info) get_route_info(e, info); else @@ -66,7 +66,7 @@ rt_show_rte(struct cli *c, byte *ia, rte *e, struct rt_show_data *d, int primary rt_show_table(c, d); cli_printf(c, -1007, "%-20s %s [%s %s%s]%s%s", ia, rta_dest_name(a->dest), - a->src->proto->name, tm, from, primary ? (sync_error ? " !" : " *") : "", info); + e->src->proto->name, tm, from, primary ? (sync_error ? " !" : " *") : "", info); if (a->dest == RTD_UNICAST) for (nh = &(a->nh); nh; nh = nh->next) @@ -180,7 +180,7 @@ rt_show_net(struct cli *c, net *n, struct rt_show_data *d) } } - if (d->show_protocol && (d->show_protocol != e->attrs->src->proto)) + if (d->show_protocol && (d->show_protocol != e->src->proto)) goto skip; if (f_run(d->filter, &e, c->show_pool, 0) > F_ACCEPT) diff --git a/nest/rt-table.c b/nest/rt-table.c index 0b06be92..a869bb18 100644 --- a/nest/rt-table.c +++ b/nest/rt-table.c @@ -264,7 +264,7 @@ rte_find(net *net, struct rte_src *src) { rte *e = net->routes; - while (e && e->attrs->src != src) + while (e && e->src != src) e = e->next; return e; } @@ -279,13 +279,14 @@ rte_find(net *net, struct rte_src *src) * the protocol. */ rte * -rte_get_temp(rta *a) +rte_get_temp(rta *a, struct rte_src *src) { rte *e = sl_alloc(rte_slab); e->attrs = a; e->id = 0; e->flags = 0; + rt_lock_source(e->src = src); return e; } @@ -295,6 +296,8 @@ rte_do_cow(rte *r) rte *e = sl_alloc(rte_slab); memcpy(e, r, sizeof(rte)); + + rt_lock_source(e->src); e->attrs = rta_clone(r->attrs); e->flags = 0; return e; @@ -341,6 +344,7 @@ rte_cow_rta(rte *r, linpool *lp) void rte_free(rte *e) { + rt_unlock_source(e->src); if (rta_is_cached(e->attrs)) rta_free(e->attrs); sl_free(rte_slab, e); @@ -349,6 +353,7 @@ rte_free(rte *e) static inline void rte_free_quick(rte *e) { + rt_unlock_source(e->src); rta_free(e->attrs); sl_free(rte_slab, e); } @@ -473,7 +478,7 @@ void rte_make_tmp_attrs(rte **r, linpool *lp, rta **old_attrs) { void (*make_tmp_attrs)(rte *r, linpool *lp); - make_tmp_attrs = (*r)->attrs->src->proto->make_tmp_attrs; + make_tmp_attrs = (*r)->src->proto->make_tmp_attrs; if (!make_tmp_attrs) return; @@ -502,7 +507,7 @@ static void rte_store_tmp_attrs(rte *r, linpool *lp, rta *old_attrs) { void (*store_tmp_attrs)(rte *rt, linpool *lp); - store_tmp_attrs = r->attrs->src->proto->store_tmp_attrs; + store_tmp_attrs = r->src->proto->store_tmp_attrs; if (!store_tmp_attrs) return; @@ -536,16 +541,16 @@ rte_better(rte *new, rte *old) return 1; if (new->attrs->pref < old->attrs->pref) return 0; - if (new->attrs->src->proto->proto != old->attrs->src->proto->proto) + if (new->src->proto->proto != old->src->proto->proto) { /* * If the user has configured protocol preferences, so that two different protocols * have the same preference, try to break the tie by comparing addresses. Not too * useful, but keeps the ordering of routes unambiguous. */ - return new->attrs->src->proto->proto > old->attrs->src->proto->proto; + return new->src->proto->proto > old->src->proto->proto; } - if (better = new->attrs->src->proto->rte_better) + if (better = new->src->proto->rte_better) return better(new, old); return 0; } @@ -561,10 +566,10 @@ rte_mergable(rte *pri, rte *sec) if (pri->attrs->pref != sec->attrs->pref) return 0; - if (pri->attrs->src->proto->proto != sec->attrs->src->proto->proto) + if (pri->src->proto->proto != sec->src->proto->proto) return 0; - if (mergable = pri->attrs->src->proto->rte_mergable) + if (mergable = pri->src->proto->rte_mergable) return mergable(pri, sec); return 0; @@ -1079,7 +1084,8 @@ rte_same(rte *x, rte *y) return x->attrs == y->attrs && x->pflags == y->pflags && - (!x->attrs->src->proto->rte_same || x->attrs->src->proto->rte_same(x, y)) && + x->src == y->src && + (!x->src->proto->rte_same || x->src->proto->rte_same(x, y)) && rte_is_filtered(x) == rte_is_filtered(y); } @@ -1100,7 +1106,7 @@ rte_recalculate(struct channel *c, net *net, rte *new, struct rte_src *src) k = &net->routes; /* Find and remove original route from the same protocol */ while (old = *k) { - if (old->attrs->src == src) + if (old->src == src) { /* If there is the same route in the routing table but from * a different sender, then there are two paths from the @@ -1561,7 +1567,7 @@ static inline void rte_discard(rte *old) /* Non-filtered route deletion, used during garbage collection */ { rte_update_lock(); - rte_recalculate(old->sender, old->net, NULL, old->attrs->src); + rte_recalculate(old->sender, old->net, NULL, old->src); rte_update_unlock(); } @@ -1581,7 +1587,7 @@ rte_modify(rte *old) new->flags = (old->flags & ~REF_MODIFY) | REF_COW; } - rte_recalculate(old->sender, old->net, new, old->attrs->src); + rte_recalculate(old->sender, old->net, new, old->src); } rte_update_unlock(); @@ -1707,8 +1713,8 @@ rte_dump(rte *e) debug("%-1N ", n->n.addr); debug("PF=%02x ", e->pflags); rta_dump(e->attrs); - if (e->attrs->src->proto->proto->dump_attrs) - e->attrs->src->proto->proto->dump_attrs(e); + if (e->src->proto->proto->dump_attrs) + e->src->proto->proto->dump_attrs(e); debug("\n"); } @@ -2222,6 +2228,7 @@ rt_next_hop_update_rte(rtable *tab UNUSED, rte *old) rte *e = sl_alloc(rte_slab); memcpy(e, old, sizeof(rte)); e->attrs = rta_lookup(a); + rt_lock_source(e->src); return e; } @@ -2248,8 +2255,8 @@ rt_next_hop_update_net(rtable *tab, net *n) /* Call a pre-comparison hook */ /* Not really an efficient way to compute this */ - if (e->attrs->src->proto->rte_recalculate) - e->attrs->src->proto->rte_recalculate(tab, n, new, e, NULL); + if (e->src->proto->rte_recalculate) + e->src->proto->rte_recalculate(tab, n, new, e, NULL); if (e != old_best) rte_free_quick(e); @@ -2584,7 +2591,7 @@ rte_update_in(struct channel *c, const net_addr *n, rte *new, struct rte_src *sr /* Find the old rte */ for (pos = &net->routes; old = *pos; pos = &old->next) - if (old->attrs->src == src) + if (old->src == src) { if (new && rte_same(old, new)) { @@ -2689,7 +2696,7 @@ rt_reload_channel(struct channel *c) return 0; } - rte_update2(c, e->net->n.addr, rte_do_cow(e), e->attrs->src); + rte_update2(c, e->net->n.addr, rte_do_cow(e), e->src); } c->reload_next_rte = NULL; @@ -2772,7 +2779,7 @@ rte_update_out(struct channel *c, const net_addr *n, rte *new, rte *old0, rte ** if (new) { net = net_get(tab, n); - src = new->attrs->src; + src = new->src; rte_store_tmp_attrs(new, rte_update_pool, NULL); @@ -2782,7 +2789,7 @@ rte_update_out(struct channel *c, const net_addr *n, rte *new, rte *old0, rte ** else { net = net_find(tab, n); - src = old0->attrs->src; + src = old0->src; if (!net) goto drop_withdraw; @@ -2790,7 +2797,7 @@ rte_update_out(struct channel *c, const net_addr *n, rte *new, rte *old0, rte ** /* Find the old rte */ for (pos = &net->routes; old = *pos; pos = &old->next) - if ((c->ra_mode != RA_ANY) || (old->attrs->src == src)) + if ((c->ra_mode != RA_ANY) || (old->src == src)) { if (new && rte_same(old, new)) { |