diff options
author | Maria Matejka <mq@ucw.cz> | 2022-03-09 13:13:05 +0100 |
---|---|---|
committer | Maria Matejka <mq@ucw.cz> | 2022-03-09 13:13:05 +0100 |
commit | 92b832380d31fc9995d6e45b3db4ce496fcb7837 (patch) | |
tree | d76415a8847aef820bb9c935a3906d670cfa7aed /proto | |
parent | 9b6db9f9b8e561d215e1df01169b15a9dfaba1b9 (diff) | |
parent | 1b9189d5fdab672f91600b7e72a1deeab277eafc (diff) |
Merge commit '1b9189d5' into haugesund
Diffstat (limited to 'proto')
-rw-r--r-- | proto/babel/babel.c | 35 | ||||
-rw-r--r-- | proto/bgp/attrs.c | 102 | ||||
-rw-r--r-- | proto/bgp/bgp.h | 16 | ||||
-rw-r--r-- | proto/bgp/packets.c | 11 | ||||
-rw-r--r-- | proto/mrt/mrt.c | 17 | ||||
-rw-r--r-- | proto/ospf/ospf.c | 8 | ||||
-rw-r--r-- | proto/ospf/rt.c | 16 | ||||
-rw-r--r-- | proto/ospf/topology.c | 12 | ||||
-rw-r--r-- | proto/ospf/topology.h | 2 | ||||
-rw-r--r-- | proto/perf/perf.c | 13 | ||||
-rw-r--r-- | proto/pipe/pipe.c | 38 | ||||
-rw-r--r-- | proto/radv/radv.c | 18 | ||||
-rw-r--r-- | proto/rip/rip.c | 25 | ||||
-rw-r--r-- | proto/rpki/rpki.c | 9 | ||||
-rw-r--r-- | proto/static/static.c | 23 |
15 files changed, 163 insertions, 182 deletions
diff --git a/proto/babel/babel.c b/proto/babel/babel.c index 30809000..c7d78b33 100644 --- a/proto/babel/babel.c +++ b/proto/babel/babel.c @@ -681,11 +681,13 @@ babel_announce_rte(struct babel_proto *p, struct babel_entry *e) if (!neigh_find(&p->p, r->next_hop, r->neigh->ifa->iface, 0)) a0.nh.flags = RNF_ONLINK; - rta *a = rta_lookup(&a0); - rte *rte = rte_get_temp(a, p->p.main_source); + rte e0 = { + .attrs = &a0, + .src = p->p.main_source, + }; e->unreachable = 0; - rte_update2(c, e->n.addr, rte, p->p.main_source); + rte_update(c, e->n.addr, &e0, p->p.main_source); } else if (e->valid && (e->router_id != p->router_id)) { @@ -697,18 +699,19 @@ babel_announce_rte(struct babel_proto *p, struct babel_entry *e) .pref = 1, }; - 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 { /* Retraction */ e->unreachable = 0; - rte_update2(c, e->n.addr, NULL, p->p.main_source); + rte_update(c, e->n.addr, NULL, p->p.main_source); } } @@ -718,7 +721,7 @@ babel_announce_retraction(struct babel_proto *p, struct babel_entry *e) { struct channel *c = (e->n.addr->type == NET_IP4) ? p->ip4_channel : p->ip6_channel; e->unreachable = 0; - rte_update2(c, e->n.addr, NULL, p->p.main_source); + rte_update(c, e->n.addr, NULL, p->p.main_source); } @@ -2257,11 +2260,11 @@ babel_kick_timer(struct babel_proto *p) static int -babel_preexport(struct proto *P, struct rte *new) +babel_preexport(struct channel *c, struct rte *new) { struct rta *a = new->attrs; /* Reject our own unreachable routes */ - if ((a->dest == RTD_UNREACHABLE) && (new->src->proto == P)) + if ((a->dest == RTD_UNREACHABLE) && (new->src->proto == c->proto)) return -1; return 0; @@ -2272,8 +2275,8 @@ babel_preexport(struct proto *P, struct rte *new) * so store it into our data structures. */ static void -babel_rt_notify(struct proto *P, struct channel *c UNUSED, struct network *net, - struct rte *new, struct rte *old UNUSED) +babel_rt_notify(struct proto *P, struct channel *c UNUSED, const net_addr *net, + struct rte *new, const struct rte *old UNUSED) { struct babel_proto *p = (void *) P; struct babel_entry *e; @@ -2301,11 +2304,11 @@ babel_rt_notify(struct proto *P, struct channel *c UNUSED, struct network *net, if (rt_metric > BABEL_INFINITY) { log(L_WARN "%s: Invalid babel_metric value %u for route %N", - p->p.name, rt_metric, net->n.addr); + p->p.name, rt_metric, net); rt_metric = BABEL_INFINITY; } - e = babel_get_entry(p, net->n.addr); + e = babel_get_entry(p, net); /* Activate triggered updates */ if ((e->valid != BABEL_ENTRY_VALID) || @@ -2323,7 +2326,7 @@ babel_rt_notify(struct proto *P, struct channel *c UNUSED, struct network *net, else { /* Withdraw */ - e = babel_find_entry(p, net->n.addr); + e = babel_find_entry(p, net); if (!e || e->valid != BABEL_ENTRY_VALID) return; diff --git a/proto/bgp/attrs.c b/proto/bgp/attrs.c index 65e87c96..1b36368f 100644 --- a/proto/bgp/attrs.c +++ b/proto/bgp/attrs.c @@ -336,26 +336,26 @@ bgp_aigp_set_metric(struct linpool *pool, const struct adata *ad, u64 metric) } int -bgp_total_aigp_metric_(rte *e, u64 *metric, const struct adata **ad) +bgp_total_aigp_metric_(struct rta *a, u64 *metric, const struct adata **ad) { - eattr *a = ea_find(e->attrs->eattrs, EA_CODE(PROTOCOL_BGP, BA_AIGP)); - if (!a) + eattr *ea = ea_find(a->eattrs, EA_CODE(PROTOCOL_BGP, BA_AIGP)); + if (!ea) return 0; - const byte *b = bgp_aigp_get_tlv(a->u.ptr, BGP_AIGP_METRIC); + const byte *b = bgp_aigp_get_tlv(ea->u.ptr, BGP_AIGP_METRIC); if (!b) return 0; u64 aigp = get_u64(b + 3); - u64 step = e->attrs->igp_metric; + u64 step = a->igp_metric; - if (!rte_resolvable(e) || (step >= IGP_METRIC_UNKNOWN)) + if (!rta_resolvable(a) || (step >= IGP_METRIC_UNKNOWN)) step = BGP_AIGP_MAX; if (!step) step = 1; - *ad = a->u.ptr; + *ad = ea->u.ptr; *metric = aigp + step; if (*metric < aigp) *metric = BGP_AIGP_MAX; @@ -377,7 +377,7 @@ bgp_init_aigp_metric(rte *e, u64 *metric, const struct adata **ad) u32 bgp_rte_igp_metric(struct rte *rt) { - u64 metric = bgp_total_aigp_metric(rt); + u64 metric = bgp_total_aigp_metric(rt->attrs); return (u32) MIN(metric, (u64) IGP_METRIC_UNKNOWN); } @@ -906,7 +906,7 @@ bgp_decode_large_community(struct bgp_parse_state *s, uint code UNUSED, uint fla static void bgp_export_mpls_label_stack(struct bgp_export_state *s, eattr *a) { - net_addr *n = s->route->net->n.addr; + const net_addr *n = s->route->net; u32 *labels = (u32 *) a->u.ptr->data; uint lnum = a->u.ptr->length / 4; @@ -1631,7 +1631,7 @@ bgp_free_prefix_table(struct bgp_channel *c) } static struct bgp_prefix * -bgp_get_prefix(struct bgp_channel *c, net_addr *net, u32 path_id) +bgp_get_prefix(struct bgp_channel *c, const net_addr *net, u32 path_id) { u32 hash = net_hash(net) ^ u32_hash(path_id); struct bgp_prefix *px = HASH_FIND(c->prefix_hash, PXH, net, path_id, hash); @@ -1675,10 +1675,10 @@ bgp_free_prefix(struct bgp_channel *c, struct bgp_prefix *px) */ int -bgp_preexport(struct proto *P, rte *e) +bgp_preexport(struct channel *c, rte *e) { struct proto *SRC = e->src->proto; - struct bgp_proto *p = (struct bgp_proto *) P; + struct bgp_proto *p = (struct bgp_proto *) (c->proto); struct bgp_proto *src = (SRC->proto == &proto_bgp) ? (struct bgp_proto *) SRC : NULL; /* Reject our routes */ @@ -1690,8 +1690,8 @@ bgp_preexport(struct proto *P, rte *e) return 0; /* Reject flowspec that failed validation */ - if ((e->attrs->dest == RTD_UNREACHABLE) && net_is_flow(e->net->n.addr)) - return -1; + if ((e->attrs->dest == RTD_UNREACHABLE) && net_is_flow(e->net)) + return -1; /* IBGP route reflection, RFC 4456 */ if (p->is_internal && src->is_internal && (p->local_as == src->local_as)) @@ -1707,11 +1707,11 @@ bgp_preexport(struct proto *P, rte *e) } /* Handle well-known communities, RFC 1997 */ - struct eattr *c; + struct eattr *com; if (p->cf->interpret_communities && - (c = ea_find(e->attrs->eattrs, EA_CODE(PROTOCOL_BGP, BA_COMMUNITY)))) + (com = ea_find(e->attrs->eattrs, EA_CODE(PROTOCOL_BGP, BA_COMMUNITY)))) { - const struct adata *d = c->u.ptr; + const struct adata *d = com->u.ptr; /* Do not export anywhere */ if (int_set_contains(d, BGP_COMM_NO_ADVERTISE)) @@ -1791,7 +1791,7 @@ bgp_update_attrs(struct bgp_proto *p, struct bgp_channel *c, rte *e, ea_list *at /* AIGP attribute - accumulate local metric or originate new one */ u64 metric; if (s.local_next_hop && - (bgp_total_aigp_metric_(e, &metric, &ad) || + (bgp_total_aigp_metric_(e->attrs, &metric, &ad) || (c->cf->aigp_originate && bgp_init_aigp_metric(e, &metric, &ad)))) { ad = bgp_aigp_set_metric(pool, ad, metric); @@ -1850,7 +1850,7 @@ bgp_update_attrs(struct bgp_proto *p, struct bgp_channel *c, rte *e, ea_list *at } void -bgp_rt_notify(struct proto *P, struct channel *C, net *n, rte *new, rte *old) +bgp_rt_notify(struct proto *P, struct channel *C, const net_addr *n, rte *new, const rte *old) { struct bgp_proto *p = (void *) P; struct bgp_channel *c = (void *) C; @@ -1864,7 +1864,7 @@ bgp_rt_notify(struct proto *P, struct channel *C, net *n, rte *new, rte *old) /* Error during attribute processing */ if (!attrs) - log(L_ERR "%s: Invalid route %N withdrawn", p->p.name, n->n.addr); + log(L_ERR "%s: Invalid route %N withdrawn", p->p.name, n); /* If attributes are invalid, we fail back to withdraw */ buck = attrs ? bgp_get_bucket(c, attrs) : bgp_get_withdraw_bucket(c); @@ -1876,7 +1876,7 @@ bgp_rt_notify(struct proto *P, struct channel *C, net *n, rte *new, rte *old) path = old->src->global_id; } - px = bgp_get_prefix(c, n->n.addr, c->add_path_tx ? path : 0); + px = bgp_get_prefix(c, n, c->add_path_tx ? path : 0); add_tail(&buck->prefixes, &px->buck_node); bgp_schedule_packet(p->conn, c, PKT_UPDATE); @@ -1937,8 +1937,8 @@ bgp_rte_better(rte *new, rte *old) return 1; /* RFC 4271 9.1.2.1. Route resolvability test */ - n = rte_resolvable(new); - o = rte_resolvable(old); + n = rta_resolvable(new->attrs); + o = rta_resolvable(old->attrs); if (n > o) return 1; if (n < o) @@ -1963,8 +1963,8 @@ bgp_rte_better(rte *new, rte *old) return 0; /* RFC 7311 4.1 - Apply AIGP metric */ - u64 n2 = bgp_total_aigp_metric(new); - u64 o2 = bgp_total_aigp_metric(old); + u64 n2 = bgp_total_aigp_metric(new->attrs); + u64 o2 = bgp_total_aigp_metric(old->attrs); if (n2 < o2) return 1; if (n2 > o2) @@ -2079,7 +2079,7 @@ bgp_rte_mergable(rte *pri, rte *sec) return 0; /* RFC 4271 9.1.2.1. Route resolvability test */ - if (rte_resolvable(pri) != rte_resolvable(sec)) + if (rta_resolvable(pri->attrs) != rta_resolvable(sec->attrs)) return 0; /* Start with local preferences */ @@ -2148,16 +2148,15 @@ same_group(rte *r, u32 lpref, u32 lasn) } static inline int -use_deterministic_med(rte *r) +use_deterministic_med(struct rte_storage *r) { - struct proto *P = r->src->proto; + struct proto *P = r->rte.src->proto; return (P->proto == &proto_bgp) && ((struct bgp_proto *) P)->cf->deterministic_med; } 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 lasn = bgp_get_neighbor(key); @@ -2225,13 +2224,13 @@ bgp_rte_recalculate(rtable *table, net *net, rte *new, rte *old, rte *old_best) } /* The default case - find a new best-in-group route */ - r = new; /* new may not be in the list */ - for (s=net->routes; rte_is_valid(s); s=s->next) - if (use_deterministic_med(s) && same_group(s, lpref, lasn)) + rte *r = new; /* new may not be in the list */ + for (struct rte_storage *s = net->routes; rte_is_valid(s); s = s->next) + if (use_deterministic_med(s) && same_group(&s->rte, lpref, lasn)) { - s->pflags |= BGP_REF_SUPPRESSED; - if (!r || bgp_rte_better(s, r)) - r = s; + s->rte.pflags |= BGP_REF_SUPPRESSED; + if (!r || bgp_rte_better(&s->rte, r)) + r = &s->rte; } /* Simple case - the last route in group disappears */ @@ -2243,10 +2242,10 @@ bgp_rte_recalculate(rtable *table, net *net, rte *new, rte *old, rte *old_best) new->pflags &= ~BGP_REF_SUPPRESSED; /* Found all existing routes mergable with best-in-group */ - for (s=net->routes; rte_is_valid(s); s=s->next) - if (use_deterministic_med(s) && same_group(s, lpref, lasn)) - if ((s != r) && bgp_rte_mergable(r, s)) - s->pflags &= ~BGP_REF_SUPPRESSED; + for (struct rte_storage *s = net->routes; rte_is_valid(s); s = s->next) + if (use_deterministic_med(s) && same_group(&s->rte, lpref, lasn)) + if ((&s->rte != r) && bgp_rte_mergable(r, &s->rte)) + s->rte.pflags &= ~BGP_REF_SUPPRESSED; /* Found best-in-group */ r->pflags &= ~BGP_REF_SUPPRESSED; @@ -2281,12 +2280,12 @@ bgp_rte_recalculate(rtable *table, net *net, rte *new, rte *old, rte *old_best) return !old_suppressed; } -struct rte * +rte * bgp_rte_modify_stale(struct rte *r, struct linpool *pool) { - eattr *a = ea_find(r->attrs->eattrs, EA_CODE(PROTOCOL_BGP, BA_COMMUNITY)); - const struct adata *ad = a ? a->u.ptr : NULL; - uint flags = a ? a->flags : BAF_PARTIAL; + eattr *ea = ea_find(r->attrs->eattrs, EA_CODE(PROTOCOL_BGP, BA_COMMUNITY)); + const struct adata *ad = ea ? ea->u.ptr : NULL; + uint flags = ea ? ea->flags : BAF_PARTIAL; if (ad && int_set_contains(ad, BGP_COMM_NO_LLGR)) return NULL; @@ -2294,12 +2293,17 @@ bgp_rte_modify_stale(struct rte *r, struct linpool *pool) if (ad && int_set_contains(ad, BGP_COMM_LLGR_STALE)) return r; - r = rte_cow_rta(r, pool); - bgp_set_attr_ptr(&(r->attrs->eattrs), pool, BA_COMMUNITY, flags, + rta *a = rta_do_cow(r->attrs, pool); + + _Thread_local static rte e0; + e0 = *r; + e0.attrs = a; + + bgp_set_attr_ptr(&(a->eattrs), pool, BA_COMMUNITY, flags, int_set_add(pool, ad, BGP_COMM_LLGR_STALE)); - r->pflags |= BGP_REF_STALE; + e0.pflags |= BGP_REF_STALE; - return r; + return &e0; } @@ -2390,14 +2394,14 @@ bgp_get_route_info(rte *e, byte *buf) if (rte_stale(e)) buf += bsprintf(buf, "s"); - u64 metric = bgp_total_aigp_metric(e); + u64 metric = bgp_total_aigp_metric(e->attrs); if (metric < BGP_AIGP_MAX) { buf += bsprintf(buf, "/%lu", metric); } else if (e->attrs->igp_metric) { - if (!rte_resolvable(e)) + if (!rta_resolvable(e->attrs)) buf += bsprintf(buf, "/-"); else if (e->attrs->igp_metric >= IGP_METRIC_UNKNOWN) buf += bsprintf(buf, "/?"); diff --git a/proto/bgp/bgp.h b/proto/bgp/bgp.h index bff49c3a..655b2636 100644 --- a/proto/bgp/bgp.h +++ b/proto/bgp/bgp.h @@ -518,9 +518,9 @@ struct rte_source *bgp_find_source(struct bgp_proto *p, u32 path_id); struct rte_source *bgp_get_source(struct bgp_proto *p, u32 path_id); static inline int -rte_resolvable(rte *rt) +rta_resolvable(rta *a) { - return rt->attrs->dest != RTD_UNREACHABLE; + return a->dest != RTD_UNREACHABLE; } @@ -588,22 +588,22 @@ int bgp_rte_mergable(rte *pri, rte *sec); int bgp_rte_recalculate(rtable *table, net *net, rte *new, rte *old, rte *old_best); struct rte *bgp_rte_modify_stale(struct rte *r, struct linpool *pool); u32 bgp_rte_igp_metric(struct rte *); -void bgp_rt_notify(struct proto *P, struct channel *C, net *n, rte *new, rte *old); -int bgp_preexport(struct proto *, struct rte *); +void bgp_rt_notify(struct proto *P, struct channel *C, const net_addr *n, rte *new, const rte *old); +int bgp_preexport(struct channel *, struct rte *); int bgp_get_attr(const struct eattr *e, byte *buf, int buflen); -void bgp_get_route_info(struct rte *, byte *buf); -int bgp_total_aigp_metric_(rte *e, u64 *metric, const struct adata **ad); +void bgp_get_route_info(struct rte *, byte *); +int bgp_total_aigp_metric_(rta *a, u64 *metric, const struct adata **ad); #define BGP_AIGP_METRIC 1 #define BGP_AIGP_MAX U64(0xffffffffffffffff) static inline u64 -bgp_total_aigp_metric(rte *r) +bgp_total_aigp_metric(rta *a) { u64 metric = BGP_AIGP_MAX; const struct adata *ad; - bgp_total_aigp_metric_(r, &metric, &ad); + bgp_total_aigp_metric_(a, &metric, &ad); return metric; } diff --git a/proto/bgp/packets.c b/proto/bgp/packets.c index 66f14150..7be34677 100644 --- a/proto/bgp/packets.c +++ b/proto/bgp/packets.c @@ -1376,7 +1376,7 @@ bgp_rte_update(struct bgp_parse_state *s, const net_addr *n, u32 path_id, rta *a REPORT("Invalid route %N withdrawn", n); /* Route withdraw */ - rte_update3(&s->channel->c, n, NULL, s->last_src); + rte_update(&s->channel->c, n, NULL, s->last_src); return; } @@ -1389,11 +1389,12 @@ bgp_rte_update(struct bgp_parse_state *s, const net_addr *n, u32 path_id, rta *a a0->eattrs = ea; } - rta *a = rta_clone(s->cached_rta); - rte *e = rte_get_temp(a, s->last_src); + rte e0 = { + .attrs = s->cached_rta, + .src = s->last_src, + }; - e->pflags = 0; - rte_update3(&s->channel->c, n, e, s->last_src); + rte_update(&s->channel->c, n, &e0, s->last_src); } static void diff --git a/proto/mrt/mrt.c b/proto/mrt/mrt.c index e885611a..03f0d59e 100644 --- a/proto/mrt/mrt.c +++ b/proto/mrt/mrt.c @@ -460,7 +460,7 @@ mrt_rib_table_entry_bgp_attrs(struct mrt_table_dump_state *s, rte *r) return; fail: - mrt_log(s, "Attribute list too long for %N", r->net->n.addr); + mrt_log(s, "Attribute list too long for %N", r->net); } #endif @@ -512,24 +512,21 @@ mrt_rib_table_dump(struct mrt_table_dump_state *s, net *n, int add_path) mrt_init_message(&s->buf, MRT_TABLE_DUMP_V2, subtype); mrt_rib_table_header(s, n->n.addr); - rte *rt, *rt0; - for (rt0 = n->routes; rt = rt0; rt0 = rt0->next) + for (struct rte_storage *rt, *rt0 = n->routes; rt = rt0; rt0 = rt0->next) { - if (rte_is_filtered(rt)) + if (rte_is_filtered(&rt->rte)) continue; /* Skip routes that should be reported in the other phase */ - if (!s->always_add_path && (!rt->src->private_id != !s->add_path)) + if (!s->always_add_path && (!rt->rte.src->private_id != !s->add_path)) { s->want_add_path = 1; continue; } - if (f_run(s->filter, &rt, s->linpool, 0) <= F_ACCEPT) - mrt_rib_table_entry(s, rt); - - if (rt != rt0) - rte_free(rt); + rte e = rt->rte; + if (f_run(s->filter, &e, s->linpool, 0) <= F_ACCEPT) + mrt_rib_table_entry(s, &e); lp_flush(s->linpool); } diff --git a/proto/ospf/ospf.c b/proto/ospf/ospf.c index f9aa6cd1..22150590 100644 --- a/proto/ospf/ospf.c +++ b/proto/ospf/ospf.c @@ -107,7 +107,7 @@ #include <stdlib.h> #include "ospf.h" -static int ospf_preexport(struct proto *P, rte *new); +static int ospf_preexport(struct channel *C, rte *new); static void ospf_reload_routes(struct channel *C); static int ospf_rte_better(struct rte *new, struct rte *old); static u32 ospf_rte_igp_metric(struct rte *rt); @@ -482,13 +482,13 @@ ospf_disp(timer * timer) * import to the filters. */ static int -ospf_preexport(struct proto *P, rte *e) +ospf_preexport(struct channel *c, rte *e) { - struct ospf_proto *p = (struct ospf_proto *) P; + struct ospf_proto *p = (struct ospf_proto *) c->proto; struct ospf_area *oa = ospf_main_area(p); /* Reject our own routes */ - if (e->src->proto == P) + if (e->src->proto == c->proto) return -1; /* Do not export routes to stub areas */ diff --git a/proto/ospf/rt.c b/proto/ospf/rt.c index 471bb586..3e208023 100644 --- a/proto/ospf/rt.c +++ b/proto/ospf/rt.c @@ -2096,15 +2096,18 @@ again1: .u.data = nf->n.rid, }; - 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); - rte_update(&p->p, nf->fn.addr, e); + + rte_update(p->p.main_channel, nf->fn.addr, &e0, p->p.main_source); } } else if (nf->old_rta) @@ -2113,7 +2116,7 @@ again1: rta_free(nf->old_rta); nf->old_rta = NULL; - rte_update(&p->p, nf->fn.addr, NULL); + rte_update(p->p.main_channel, nf->fn.addr, NULL, p->p.main_source); } /* Remove unused rt entry, some special entries are persistent */ @@ -2129,7 +2132,6 @@ again1: } FIB_ITERATE_END; - WALK_LIST(oa, p->area_list) { /* Cleanup ASBR hash tables */ diff --git a/proto/ospf/topology.c b/proto/ospf/topology.c index 52c2a0ce..bb88d20a 100644 --- a/proto/ospf/topology.c +++ b/proto/ospf/topology.c @@ -1300,7 +1300,7 @@ find_surrogate_fwaddr(struct ospf_proto *p, struct ospf_area *oa) } void -ospf_rt_notify(struct proto *P, struct channel *ch UNUSED, net *n, rte *new, rte *old UNUSED) +ospf_rt_notify(struct proto *P, struct channel *ch UNUSED, const net_addr *n, rte *new, const rte *old UNUSED) { struct ospf_proto *p = (struct ospf_proto *) P; struct ospf_area *oa = NULL; /* non-NULL for NSSA-LSA */ @@ -1319,7 +1319,7 @@ ospf_rt_notify(struct proto *P, struct channel *ch UNUSED, net *n, rte *new, rte if (!new) { - nf = fib_find(&p->rtf, n->n.addr); + nf = fib_find(&p->rtf, n); if (!nf || !nf->external_rte) return; @@ -1346,14 +1346,14 @@ ospf_rt_notify(struct proto *P, struct channel *ch UNUSED, net *n, rte *new, rte if (m1 > LSINFINITY) { log(L_WARN "%s: Invalid ospf_metric1 value %u for route %N", - p->p.name, m1, n->n.addr); + p->p.name, m1, n); m1 = LSINFINITY; } if (m2 > LSINFINITY) { log(L_WARN "%s: Invalid ospf_metric2 value %u for route %N", - p->p.name, m2, n->n.addr); + p->p.name, m2, n); m2 = LSINFINITY; } @@ -1377,12 +1377,12 @@ ospf_rt_notify(struct proto *P, struct channel *ch UNUSED, net *n, rte *new, rte if (ipa_zero(fwd)) { log(L_ERR "%s: Cannot find forwarding address for NSSA-LSA %N", - p->p.name, n->n.addr); + p->p.name, n); return; } } - nf = fib_get(&p->rtf, n->n.addr); + nf = fib_get(&p->rtf, n); ospf_originate_ext_lsa(p, oa, nf, LSA_M_EXPORT, metric, ebit, fwd, tag, 1, p->vpn_pe); nf->external_rte = 1; } diff --git a/proto/ospf/topology.h b/proto/ospf/topology.h index 535d1f1b..c36d0b50 100644 --- a/proto/ospf/topology.h +++ b/proto/ospf/topology.h @@ -200,7 +200,7 @@ void ospf_originate_sum_rt_lsa(struct ospf_proto *p, struct ospf_area *oa, u32 d void ospf_originate_ext_lsa(struct ospf_proto *p, struct ospf_area *oa, ort *nf, u8 mode, u32 metric, u32 ebit, ip_addr fwaddr, u32 tag, int pbit, int dn); void ospf_originate_gr_lsa(struct ospf_proto *p, struct ospf_iface *ifa); -void ospf_rt_notify(struct proto *P, struct channel *ch, net *n, rte *new, rte *old); +void ospf_rt_notify(struct proto *P, struct channel *ch, const net_addr *n, rte *new, const rte *old); void ospf_update_topology(struct ospf_proto *p); struct top_hash_entry *ospf_hash_find(struct top_graph *, u32 domain, u32 lsa, u32 rtr, u32 type); diff --git a/proto/perf/perf.c b/proto/perf/perf.c index 52784c14..8b2cb69f 100644 --- a/proto/perf/perf.c +++ b/proto/perf/perf.c @@ -160,18 +160,17 @@ perf_loop(void *data) clock_gettime(CLOCK_MONOTONIC, &ts_generated); - for (uint i=0; i<N; i++) { - rte *e = rte_get_temp(p->data[i].a, p->p.main_source); - e->pflags = 0; - - rte_update(P, &(p->data[i].net), e); + for (uint i=0; i<N; i++) + { + rte e0 = { .attrs = p->data[i].a, .src = P->main_source, }; + rte_update(P->main_channel, &(p->data[i].net), &e0, P->main_source); } clock_gettime(CLOCK_MONOTONIC, &ts_update); if (!p->keep) for (uint i=0; i<N; i++) - rte_update(P, &(p->data[i].net), NULL); + rte_update(P->main_channel, &(p->data[i].net), NULL, P->main_source); clock_gettime(CLOCK_MONOTONIC, &ts_withdraw); @@ -204,7 +203,7 @@ perf_loop(void *data) } static void -perf_rt_notify(struct proto *P, struct channel *c UNUSED, struct network *net UNUSED, struct rte *new UNUSED, struct rte *old UNUSED) +perf_rt_notify(struct proto *P, struct channel *c UNUSED, const net_addr *net UNUSED, struct rte *new UNUSED, const struct rte *old UNUSED) { struct perf_proto *p = (struct perf_proto *) P; p->exp++; diff --git a/proto/pipe/pipe.c b/proto/pipe/pipe.c index 97862780..3caa85d0 100644 --- a/proto/pipe/pipe.c +++ b/proto/pipe/pipe.c @@ -48,14 +48,10 @@ #endif static void -pipe_rt_notify(struct proto *P, struct channel *src_ch, net *n, rte *new, rte *old) +pipe_rt_notify(struct proto *P, struct channel *src_ch, const net_addr *n, rte *new, const rte *old) { struct pipe_proto *p = (void *) P; struct channel *dst = (src_ch == p->pri) ? p->sec : p->pri; - struct rte_src *src; - - rte *e; - rta *a; if (!new && !old) return; @@ -63,45 +59,39 @@ pipe_rt_notify(struct proto *P, struct channel *src_ch, net *n, rte *new, rte *o if (dst->table->pipe_busy) { log(L_ERR "Pipe loop detected when sending %N to table %s", - n->n.addr, dst->table->name); + n, dst->table->name); return; } + src_ch->table->pipe_busy = 1; + if (new) { - src = new->src; - - a = alloca(rta_size(new->attrs)); + rta *a = alloca(rta_size(new->attrs)); memcpy(a, new->attrs, rta_size(new->attrs)); a->cached = 0; a->hostentry = NULL; - e = rte_get_temp(a, src); - e->pflags = new->pflags; -#ifdef CONFIG_BGP - /* Hack to cleanup cached value */ - if (e->src->proto->proto == &proto_bgp) - e->pflags &= ~(BGP_REF_STALE | BGP_REF_NOT_STALE); -#endif + rte e0 = { + .attrs = a, + .src = new->src, + }; + + rte_update(dst, n, &e0, new->src); } else - { - e = NULL; - src = old->src; - } + rte_update(dst, n, NULL, old->src); - src_ch->table->pipe_busy = 1; - rte_update2(dst, n->n.addr, e, src); src_ch->table->pipe_busy = 0; } static int -pipe_preexport(struct proto *P, rte *e) +pipe_preexport(struct channel *c, rte *e) { struct proto *pp = e->sender->proto; - if (pp == P) + if (pp == c->proto) return -1; /* Avoid local loops automatically */ return 0; diff --git a/proto/radv/radv.c b/proto/radv/radv.c index 540ff2a7..fa228c69 100644 --- a/proto/radv/radv.c +++ b/proto/radv/radv.c @@ -385,16 +385,16 @@ radv_trigger_valid(struct radv_config *cf) } static inline int -radv_net_match_trigger(struct radv_config *cf, net *n) +radv_net_match_trigger(struct radv_config *cf, const net_addr *n) { - return radv_trigger_valid(cf) && net_equal(n->n.addr, &cf->trigger); + return radv_trigger_valid(cf) && net_equal(n, &cf->trigger); } int -radv_preexport(struct proto *P, rte *new) +radv_preexport(struct channel *c, rte *new) { // struct radv_proto *p = (struct radv_proto *) P; - struct radv_config *cf = (struct radv_config *) (P->cf); + struct radv_config *cf = (struct radv_config *) (c->proto->cf); if (radv_net_match_trigger(cf, new->net)) return RIC_PROCESS; @@ -406,7 +406,7 @@ radv_preexport(struct proto *P, rte *new) } static void -radv_rt_notify(struct proto *P, struct channel *ch UNUSED, net *n, rte *new, rte *old UNUSED) +radv_rt_notify(struct proto *P, struct channel *ch UNUSED, const net_addr *n, rte *new, const rte *old UNUSED) { struct radv_proto *p = (struct radv_proto *) P; struct radv_config *cf = (struct radv_config *) (P->cf); @@ -457,14 +457,14 @@ radv_rt_notify(struct proto *P, struct channel *ch UNUSED, net *n, rte *new, rte (preference != RA_PREF_HIGH)) { log(L_WARN "%s: Invalid ra_preference value %u on route %N", - p->p.name, preference, n->n.addr); + p->p.name, preference, n); preference = RA_PREF_MEDIUM; preference_set = 1; lifetime = 0; lifetime_set = 1; } - rt = fib_get(&p->routes, n->n.addr); + rt = fib_get(&p->routes, n); /* Ignore update if nothing changed */ if (rt->valid && @@ -487,7 +487,7 @@ radv_rt_notify(struct proto *P, struct channel *ch UNUSED, net *n, rte *new, rte else { /* Withdraw */ - rt = fib_find(&p->routes, n->n.addr); + rt = fib_find(&p->routes, n); if (!rt || !rt->valid) return; @@ -555,7 +555,7 @@ radv_check_active(struct radv_proto *p) return 1; struct channel *c = p->p.main_channel; - return rt_examine(c->table, &cf->trigger, &p->p, c->out_filter); + return rt_examine(c->table, &cf->trigger, c, c->out_filter); } static void diff --git a/proto/rip/rip.c b/proto/rip/rip.c index a501a784..0a9844f3 100644 --- a/proto/rip/rip.c +++ b/proto/rip/rip.c @@ -207,16 +207,15 @@ rip_announce_rte(struct rip_proto *p, struct rip_entry *en) .u.data = (uintptr_t) a0.nh.iface, }; - rta *a = rta_lookup(&a0); - rte *e = rte_get_temp(a, p->p.main_source); + rte e0 = { + .attrs = &a0, + .src = p->p.main_source, + }; - rte_update(&p->p, en->n.addr, e); + rte_update(p->p.main_channel, en->n.addr, &e0, p->p.main_source); } else - { - /* Withdraw */ - rte_update(&p->p, en->n.addr, NULL); - } + rte_update(p->p.main_channel, en->n.addr, NULL, p->p.main_source); } /** @@ -311,8 +310,8 @@ rip_withdraw_rte(struct rip_proto *p, net_addr *n, struct rip_neighbor *from) * it into our data structures. */ static void -rip_rt_notify(struct proto *P, struct channel *ch UNUSED, struct network *net, struct rte *new, - struct rte *old UNUSED) +rip_rt_notify(struct proto *P, struct channel *ch UNUSED, const net_addr *net, struct rte *new, + const struct rte *old UNUSED) { struct rip_proto *p = (struct rip_proto *) P; struct rip_entry *en; @@ -328,14 +327,14 @@ rip_rt_notify(struct proto *P, struct channel *ch UNUSED, struct network *net, s if (rt_metric > p->infinity) { log(L_WARN "%s: Invalid rip_metric value %u for route %N", - p->p.name, rt_metric, net->n.addr); + p->p.name, rt_metric, net); rt_metric = p->infinity; } if (rt_tag > 0xffff) { log(L_WARN "%s: Invalid rip_tag value %u for route %N", - p->p.name, rt_tag, net->n.addr); + p->p.name, rt_tag, net); rt_metric = p->infinity; rt_tag = 0; } @@ -347,7 +346,7 @@ rip_rt_notify(struct proto *P, struct channel *ch UNUSED, struct network *net, s * collection. */ - en = fib_get(&p->rtable, net->n.addr); + en = fib_get(&p->rtable, net); old_metric = en->valid ? en->metric : -1; @@ -361,7 +360,7 @@ rip_rt_notify(struct proto *P, struct channel *ch UNUSED, struct network *net, s else { /* Withdraw */ - en = fib_find(&p->rtable, net->n.addr); + en = fib_find(&p->rtable, net); if (!en || en->valid != RIP_ENTRY_VALID) return; diff --git a/proto/rpki/rpki.c b/proto/rpki/rpki.c index be3d19ab..72fbc967 100644 --- a/proto/rpki/rpki.c +++ b/proto/rpki/rpki.c @@ -127,19 +127,16 @@ rpki_table_add_roa(struct rpki_cache *cache, struct channel *channel, const net_ .dest = RTD_NONE, }; - 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 rpki_table_remove_roa(struct rpki_cache *cache, struct channel *channel, const net_addr_union *pfxr) { struct rpki_proto *p = cache->p; - rte_update2(channel, &pfxr->n, NULL, p->p.main_source); + rte_update(channel, &pfxr->n, NULL, p->p.main_source); } diff --git a/proto/static/static.c b/proto/static/static.c index 6d3871cc..6e258f6f 100644 --- a/proto/static/static.c +++ b/proto/static/static.c @@ -103,24 +103,13 @@ static_announce_rte(struct static_proto *p, struct static_route *r) return; /* We skip rta_lookup() here */ - rte *e = rte_get_temp(a, src); - e->pflags = 0; + rte e0 = { .attrs = a, .src = src, .net = r->net, }, *e = &e0; + /* Evaluate the filter */ if (r->cmds) - { - /* Create a temporary table node */ - e->net = alloca(sizeof(net) + r->net->length); - memset(e->net, 0, sizeof(net) + r->net->length); - net_copy(e->net->n.addr, r->net); - - /* Evaluate the filter */ - f_eval_rte(r->cmds, &e, static_lp); - - /* Remove the temporary node */ - e->net = NULL; - } + f_eval_rte(r->cmds, e, static_lp); - rte_update2(p->p.main_channel, r->net, e, src); + rte_update(p->p.main_channel, r->net, e, src); r->state = SRS_CLEAN; if (r->cmds) @@ -132,7 +121,7 @@ withdraw: if (r->state == SRS_DOWN) return; - rte_update2(p->p.main_channel, r->net, NULL, src); + rte_update(p->p.main_channel, r->net, NULL, src); r->state = SRS_DOWN; } @@ -298,7 +287,7 @@ static void static_remove_rte(struct static_proto *p, struct static_route *r) { if (r->state) - rte_update2(p->p.main_channel, r->net, NULL, static_get_source(p, r->index)); + rte_update(p->p.main_channel, r->net, NULL, static_get_source(p, r->index)); static_reset_rte(p, r); } |