diff options
author | Maria Matejka <mq@ucw.cz> | 2022-05-30 12:03:03 +0200 |
---|---|---|
committer | Maria Matejka <mq@ucw.cz> | 2022-05-30 14:39:09 +0200 |
commit | 938742decc6e1d6d3a0375dd012b75172e747bbc (patch) | |
tree | a10d9eb2811af43075c2c5272ece7b3dbbb38cdf /proto | |
parent | 950775f6fa3d569a9d7cd05e33538d35e895d688 (diff) |
Squashing the route attribute structure into one level.
For now, all route attributes are stored as eattrs in ea_list. This
should make route manipulation easier and it also allows for a layered
approach of route attributes where updates from filters will be stored
as an overlay over the previous version.
Diffstat (limited to 'proto')
-rw-r--r-- | proto/babel/babel.c | 34 | ||||
-rw-r--r-- | proto/bgp/attrs.c | 66 | ||||
-rw-r--r-- | proto/bgp/bgp.h | 10 | ||||
-rw-r--r-- | proto/bgp/packets.c | 127 | ||||
-rw-r--r-- | proto/mrt/mrt.c | 2 | ||||
-rw-r--r-- | proto/ospf/ospf.c | 20 | ||||
-rw-r--r-- | proto/ospf/rt.c | 32 | ||||
-rw-r--r-- | proto/ospf/rt.h | 2 | ||||
-rw-r--r-- | proto/ospf/topology.c | 10 | ||||
-rw-r--r-- | proto/perf/perf.c | 12 | ||||
-rw-r--r-- | proto/pipe/pipe.c | 8 | ||||
-rw-r--r-- | proto/radv/radv.c | 4 | ||||
-rw-r--r-- | proto/rip/rip.c | 36 | ||||
-rw-r--r-- | proto/rpki/rpki.c | 10 | ||||
-rw-r--r-- | proto/static/static.c | 24 |
15 files changed, 186 insertions, 211 deletions
diff --git a/proto/babel/babel.c b/proto/babel/babel.c index b90dcd3f..e3903c67 100644 --- a/proto/babel/babel.c +++ b/proto/babel/babel.c @@ -677,10 +677,7 @@ babel_announce_rte(struct babel_proto *p, struct babel_entry *e) } }; - rta a0 = { .eattrs = &eattrs.l, }; - - rta *a = rta_lookup(&a0); - rte *rte = rte_get_temp(a, p->p.main_source); + rte *rte = rte_get_temp(rta_lookup(&eattrs.l), p->p.main_source); e->unreachable = 0; rte_update2(c, e->n.addr, rte, p->p.main_source); @@ -688,14 +685,13 @@ babel_announce_rte(struct babel_proto *p, struct babel_entry *e) else if (e->valid && (e->router_id != p->router_id)) { /* Unreachable */ - rta a0 = {}; + ea_list *ea = NULL; - ea_set_attr_u32(&a0.eattrs, &ea_gen_preference, 0, 1); - ea_set_attr_u32(&a0.eattrs, &ea_gen_source, 0, RTS_BABEL); - ea_set_dest(&a0.eattrs, 0, RTD_UNREACHABLE); + ea_set_attr_u32(&ea, &ea_gen_preference, 0, 1); + ea_set_attr_u32(&ea, &ea_gen_source, 0, RTS_BABEL); + ea_set_dest(&ea, 0, RTD_UNREACHABLE); - rta *a = rta_lookup(&a0); - rte *rte = rte_get_temp(a, p->p.main_source); + rte *rte = rte_get_temp(rta_lookup(ea), p->p.main_source); rte->pflags = 0; e->unreachable = 1; @@ -2025,13 +2021,13 @@ static void babel_get_route_info(rte *rte, byte *buf) { u64 rid = 0; - eattr *e = ea_find(rte->attrs->eattrs, &ea_babel_router_id); + eattr *e = ea_find(rte->attrs, &ea_babel_router_id); if (e) memcpy(&rid, e->u.ptr->data, sizeof(u64)); buf += bsprintf(buf, " (%d/%d) [%lR]", rt_get_preference(rte), - ea_get_int(rte->attrs->eattrs, &ea_babel_metric, BABEL_INFINITY), rid); + ea_get_int(rte->attrs, &ea_babel_metric, BABEL_INFINITY), rid); } static void @@ -2263,7 +2259,7 @@ babel_preexport(struct proto *P, struct rte *new) return 0; /* Reject our own unreachable routes */ - eattr *ea = ea_find(new->attrs->eattrs, &ea_gen_nexthop); + eattr *ea = ea_find(new->attrs, &ea_gen_nexthop); struct nexthop_adata *nhad = (void *) ea->u.ptr; if (!NEXTHOP_IS_REACHABLE(nhad)) return -1; @@ -2286,13 +2282,13 @@ babel_rt_notify(struct proto *P, struct channel *c UNUSED, struct network *net, { /* Update */ uint rt_seqno; - uint rt_metric = ea_get_int(new->attrs->eattrs, &ea_babel_metric, 0); + uint rt_metric = ea_get_int(new->attrs, &ea_babel_metric, 0); u64 rt_router_id = 0; if (new->src->proto == P) { - rt_seqno = ea_get_int(new->attrs->eattrs, &ea_babel_seqno, 0); - eattr *e = ea_find(new->attrs->eattrs, &ea_babel_router_id); + rt_seqno = ea_get_int(new->attrs, &ea_babel_seqno, 0); + eattr *e = ea_find(new->attrs, &ea_babel_router_id); if (e) memcpy(&rt_router_id, e->u.ptr->data, sizeof(u64)); } @@ -2343,8 +2339,8 @@ babel_rt_notify(struct proto *P, struct channel *c UNUSED, struct network *net, static int babel_rte_better(struct rte *new, struct rte *old) { - uint new_metric = ea_get_int(new->attrs->eattrs, &ea_babel_metric, BABEL_INFINITY); - uint old_metric = ea_get_int(old->attrs->eattrs, &ea_babel_metric, BABEL_INFINITY); + uint new_metric = ea_get_int(new->attrs, &ea_babel_metric, BABEL_INFINITY); + uint old_metric = ea_get_int(old->attrs, &ea_babel_metric, BABEL_INFINITY); return new_metric < old_metric; } @@ -2352,7 +2348,7 @@ babel_rte_better(struct rte *new, struct rte *old) static u32 babel_rte_igp_metric(struct rte *rt) { - return ea_get_int(rt->attrs->eattrs, &ea_babel_metric, BABEL_INFINITY); + return ea_get_int(rt->attrs, &ea_babel_metric, BABEL_INFINITY); } diff --git a/proto/bgp/attrs.c b/proto/bgp/attrs.c index 6a9e4026..c605bb07 100644 --- a/proto/bgp/attrs.c +++ b/proto/bgp/attrs.c @@ -374,7 +374,7 @@ 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) { - eattr *a = ea_find(e->attrs->eattrs, BGP_EA_ID(BA_AIGP)); + eattr *a = ea_find(e->attrs, BGP_EA_ID(BA_AIGP)); if (!a) return 0; @@ -1492,13 +1492,13 @@ loop: } void -bgp_finish_attrs(struct bgp_parse_state *s, rta *a) +bgp_finish_attrs(struct bgp_parse_state *s, ea_list **to) { /* AIGP test here instead of in bgp_decode_aigp() - we need to know channel */ if (BIT32_TEST(s->attrs_seen, BA_AIGP) && !s->channel->cf->aigp) { REPORT("Discarding AIGP attribute received on non-AIGP session"); - bgp_unset_attr(&a->eattrs, BA_AIGP); + bgp_unset_attr(to, BA_AIGP); } } @@ -1735,14 +1735,14 @@ bgp_preexport(struct proto *P, rte *e) /* Generally, this should be handled when path is received, but we check it also here as rr_cluster_id may be undefined or different in src. */ - if (p->rr_cluster_id && bgp_cluster_list_loopy(p, e->attrs->eattrs)) + if (p->rr_cluster_id && bgp_cluster_list_loopy(p, e->attrs)) return -1; } /* Handle well-known communities, RFC 1997 */ struct eattr *c; if (p->cf->interpret_communities && - (c = ea_find(e->attrs->eattrs, BGP_EA_ID(BA_COMMUNITY)))) + (c = ea_find(e->attrs, BGP_EA_ID(BA_COMMUNITY)))) { const struct adata *d = c->u.ptr; @@ -1893,7 +1893,7 @@ bgp_rt_notify(struct proto *P, struct channel *C, net *n, rte *new, rte *old) if (new) { - struct ea_list *attrs = bgp_update_attrs(p, c, new, new->attrs->eattrs, tmp_linpool); + struct ea_list *attrs = bgp_update_attrs(p, c, new, new->attrs, tmp_linpool); /* Error during attribute processing */ if (!attrs) @@ -1919,7 +1919,7 @@ bgp_rt_notify(struct proto *P, struct channel *C, net *n, rte *new, rte *old) static inline u32 bgp_get_neighbor(rte *r) { - eattr *e = ea_find(r->attrs->eattrs, BGP_EA_ID(BA_AS_PATH)); + eattr *e = ea_find(r->attrs, BGP_EA_ID(BA_AS_PATH)); u32 as; if (e && as_path_get_first_regular(e->u.ptr, &as)) @@ -1940,7 +1940,7 @@ rte_stale(rte *r) return 0; /* If staleness is unknown, compute and cache it */ - eattr *a = ea_find(r->attrs->eattrs, BGP_EA_ID(BA_COMMUNITY)); + eattr *a = ea_find(r->attrs, BGP_EA_ID(BA_COMMUNITY)); if (a && int_set_contains(a->u.ptr, BGP_COMM_LLGR_STALE)) { r->pflags |= BGP_REF_STALE; @@ -1986,8 +1986,8 @@ bgp_rte_better(rte *new, rte *old) return 1; /* Start with local preferences */ - x = ea_find(new->attrs->eattrs, BGP_EA_ID(BA_LOCAL_PREF)); - y = ea_find(old->attrs->eattrs, BGP_EA_ID(BA_LOCAL_PREF)); + x = ea_find(new->attrs, BGP_EA_ID(BA_LOCAL_PREF)); + y = ea_find(old->attrs, BGP_EA_ID(BA_LOCAL_PREF)); n = x ? x->u.data : new_bgp->cf->default_local_pref; o = y ? y->u.data : old_bgp->cf->default_local_pref; if (n > o) @@ -2006,8 +2006,8 @@ bgp_rte_better(rte *new, rte *old) /* RFC 4271 9.1.2.2. a) Use AS path lengths */ if (new_bgp->cf->compare_path_lengths || old_bgp->cf->compare_path_lengths) { - x = ea_find(new->attrs->eattrs, BGP_EA_ID(BA_AS_PATH)); - y = ea_find(old->attrs->eattrs, BGP_EA_ID(BA_AS_PATH)); + x = ea_find(new->attrs, BGP_EA_ID(BA_AS_PATH)); + y = ea_find(old->attrs, BGP_EA_ID(BA_AS_PATH)); n = x ? as_path_getlen(x->u.ptr) : AS_PATH_MAXLEN; o = y ? as_path_getlen(y->u.ptr) : AS_PATH_MAXLEN; if (n < o) @@ -2017,8 +2017,8 @@ bgp_rte_better(rte *new, rte *old) } /* RFC 4271 9.1.2.2. b) Use origins */ - x = ea_find(new->attrs->eattrs, BGP_EA_ID(BA_ORIGIN)); - y = ea_find(old->attrs->eattrs, BGP_EA_ID(BA_ORIGIN)); + x = ea_find(new->attrs, BGP_EA_ID(BA_ORIGIN)); + y = ea_find(old->attrs, BGP_EA_ID(BA_ORIGIN)); n = x ? x->u.data : ORIGIN_INCOMPLETE; o = y ? y->u.data : ORIGIN_INCOMPLETE; if (n < o) @@ -2040,8 +2040,8 @@ bgp_rte_better(rte *new, rte *old) if (new_bgp->cf->med_metric || old_bgp->cf->med_metric || (bgp_get_neighbor(new) == bgp_get_neighbor(old))) { - x = ea_find(new->attrs->eattrs, BGP_EA_ID(BA_MULTI_EXIT_DISC)); - y = ea_find(old->attrs->eattrs, BGP_EA_ID(BA_MULTI_EXIT_DISC)); + x = ea_find(new->attrs, BGP_EA_ID(BA_MULTI_EXIT_DISC)); + y = ea_find(old->attrs, BGP_EA_ID(BA_MULTI_EXIT_DISC)); n = x ? x->u.data : new_bgp->cf->default_med; o = y ? y->u.data : old_bgp->cf->default_med; if (n < o) @@ -2066,8 +2066,8 @@ bgp_rte_better(rte *new, rte *old) /* RFC 4271 9.1.2.2. f) Compare BGP identifiers */ /* RFC 4456 9. a) Use ORIGINATOR_ID instead of local neighbor ID */ - x = ea_find(new->attrs->eattrs, BGP_EA_ID(BA_ORIGINATOR_ID)); - y = ea_find(old->attrs->eattrs, BGP_EA_ID(BA_ORIGINATOR_ID)); + x = ea_find(new->attrs, BGP_EA_ID(BA_ORIGINATOR_ID)); + y = ea_find(old->attrs, BGP_EA_ID(BA_ORIGINATOR_ID)); n = x ? x->u.data : new_bgp->remote_id; o = y ? y->u.data : old_bgp->remote_id; @@ -2084,8 +2084,8 @@ bgp_rte_better(rte *new, rte *old) return 0; /* RFC 4456 9. b) Compare cluster list lengths */ - x = ea_find(new->attrs->eattrs, BGP_EA_ID(BA_CLUSTER_LIST)); - y = ea_find(old->attrs->eattrs, BGP_EA_ID(BA_CLUSTER_LIST)); + x = ea_find(new->attrs, BGP_EA_ID(BA_CLUSTER_LIST)); + y = ea_find(old->attrs, BGP_EA_ID(BA_CLUSTER_LIST)); n = x ? int_set_get_size(x->u.ptr) : 0; o = y ? int_set_get_size(y->u.ptr) : 0; if (n < o) @@ -2119,8 +2119,8 @@ bgp_rte_mergable(rte *pri, rte *sec) return 0; /* Start with local preferences */ - x = ea_find(pri->attrs->eattrs, BGP_EA_ID(BA_LOCAL_PREF)); - y = ea_find(sec->attrs->eattrs, BGP_EA_ID(BA_LOCAL_PREF)); + x = ea_find(pri->attrs, BGP_EA_ID(BA_LOCAL_PREF)); + y = ea_find(sec->attrs, BGP_EA_ID(BA_LOCAL_PREF)); p = x ? x->u.data : pri_bgp->cf->default_local_pref; s = y ? y->u.data : sec_bgp->cf->default_local_pref; if (p != s) @@ -2129,8 +2129,8 @@ bgp_rte_mergable(rte *pri, rte *sec) /* RFC 4271 9.1.2.2. a) Use AS path lengths */ if (pri_bgp->cf->compare_path_lengths || sec_bgp->cf->compare_path_lengths) { - x = ea_find(pri->attrs->eattrs, BGP_EA_ID(BA_AS_PATH)); - y = ea_find(sec->attrs->eattrs, BGP_EA_ID(BA_AS_PATH)); + x = ea_find(pri->attrs, BGP_EA_ID(BA_AS_PATH)); + y = ea_find(sec->attrs, BGP_EA_ID(BA_AS_PATH)); p = x ? as_path_getlen(x->u.ptr) : AS_PATH_MAXLEN; s = y ? as_path_getlen(y->u.ptr) : AS_PATH_MAXLEN; @@ -2142,8 +2142,8 @@ bgp_rte_mergable(rte *pri, rte *sec) } /* RFC 4271 9.1.2.2. b) Use origins */ - x = ea_find(pri->attrs->eattrs, BGP_EA_ID(BA_ORIGIN)); - y = ea_find(sec->attrs->eattrs, BGP_EA_ID(BA_ORIGIN)); + x = ea_find(pri->attrs, BGP_EA_ID(BA_ORIGIN)); + y = ea_find(sec->attrs, BGP_EA_ID(BA_ORIGIN)); p = x ? x->u.data : ORIGIN_INCOMPLETE; s = y ? y->u.data : ORIGIN_INCOMPLETE; if (p != s) @@ -2153,8 +2153,8 @@ bgp_rte_mergable(rte *pri, rte *sec) if (pri_bgp->cf->med_metric || sec_bgp->cf->med_metric || (bgp_get_neighbor(pri) == bgp_get_neighbor(sec))) { - x = ea_find(pri->attrs->eattrs, BGP_EA_ID(BA_MULTI_EXIT_DISC)); - y = ea_find(sec->attrs->eattrs, BGP_EA_ID(BA_MULTI_EXIT_DISC)); + x = ea_find(pri->attrs, BGP_EA_ID(BA_MULTI_EXIT_DISC)); + y = ea_find(sec->attrs, BGP_EA_ID(BA_MULTI_EXIT_DISC)); p = x ? x->u.data : pri_bgp->cf->default_med; s = y ? y->u.data : sec_bgp->cf->default_med; if (p != s) @@ -2320,7 +2320,7 @@ 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) { - eattr *a = ea_find(r->attrs->eattrs, BGP_EA_ID(BA_COMMUNITY)); + eattr *a = ea_find(r->attrs, BGP_EA_ID(BA_COMMUNITY)); const struct adata *ad = a ? a->u.ptr : NULL; uint flags = a ? a->flags : BAF_PARTIAL; @@ -2330,8 +2330,8 @@ 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), BA_COMMUNITY, flags, + r = rte_cow_rta(r); + bgp_set_attr_ptr(&(r->attrs), BA_COMMUNITY, flags, int_set_add(pool, ad, BGP_COMM_LLGR_STALE)); r->pflags |= BGP_REF_STALE; @@ -2388,8 +2388,8 @@ bgp_process_as4_attrs(ea_list **attrs, struct linpool *pool) void bgp_get_route_info(rte *e, byte *buf) { - eattr *p = ea_find(e->attrs->eattrs, BGP_EA_ID(BA_AS_PATH)); - eattr *o = ea_find(e->attrs->eattrs, BGP_EA_ID(BA_ORIGIN)); + eattr *p = ea_find(e->attrs, BGP_EA_ID(BA_AS_PATH)); + eattr *o = ea_find(e->attrs, BGP_EA_ID(BA_ORIGIN)); u32 origas; buf += bsprintf(buf, " (%d", rt_get_preference(e)); diff --git a/proto/bgp/bgp.h b/proto/bgp/bgp.h index 2f98dc1b..376b463f 100644 --- a/proto/bgp/bgp.h +++ b/proto/bgp/bgp.h @@ -67,10 +67,10 @@ struct bgp_af_desc { u8 no_igp; const char *name; uint (*encode_nlri)(struct bgp_write_state *s, struct bgp_bucket *buck, byte *buf, uint size); - void (*decode_nlri)(struct bgp_parse_state *s, byte *pos, uint len, rta *a); + void (*decode_nlri)(struct bgp_parse_state *s, byte *pos, uint len, ea_list *a); void (*update_next_hop)(struct bgp_export_state *s, eattr *nh, ea_list **to); uint (*encode_next_hop)(struct bgp_write_state *s, eattr *nh, byte *buf, uint size); - void (*decode_next_hop)(struct bgp_parse_state *s, byte *pos, uint len, rta *a); + void (*decode_next_hop)(struct bgp_parse_state *s, byte *pos, uint len, ea_list **to); }; @@ -461,7 +461,7 @@ struct bgp_parse_state { /* Cached state for bgp_rte_update() */ u32 last_id; struct rte_src *last_src; - rta *cached_rta; + ea_list *cached_ea; }; #define BGP_PORT 179 @@ -519,7 +519,7 @@ struct rte_source *bgp_get_source(struct bgp_proto *p, u32 path_id); static inline int rte_resolvable(rte *rt) { - eattr *nhea = ea_find(rt->attrs->eattrs, &ea_gen_nexthop); + eattr *nhea = ea_find(rt->attrs, &ea_gen_nexthop); struct nexthop_adata *nhad = (void *) nhea->u.ptr; return NEXTHOP_IS_REACHABLE(nhad) || (nhad->dest != RTD_UNREACHABLE); } @@ -551,7 +551,7 @@ int bgp_encode_mp_reach_mrt(struct bgp_write_state *s, eattr *a, byte *buf, uint int bgp_encode_attrs(struct bgp_write_state *s, ea_list *attrs, byte *buf, byte *end); ea_list * bgp_decode_attrs(struct bgp_parse_state *s, byte *data, uint len); -void bgp_finish_attrs(struct bgp_parse_state *s, rta *a); +void bgp_finish_attrs(struct bgp_parse_state *s, ea_list **to); void bgp_init_bucket_table(struct bgp_channel *c); void bgp_free_bucket_table(struct bgp_channel *c); diff --git a/proto/bgp/packets.c b/proto/bgp/packets.c index 4c46c60e..e72ec222 100644 --- a/proto/bgp/packets.c +++ b/proto/bgp/packets.c @@ -943,7 +943,7 @@ bgp_rx_open(struct bgp_conn *conn, byte *pkt, uint len) #define MISMATCHED_AF " - mismatched address family (%I for %s)" static void -bgp_apply_next_hop(struct bgp_parse_state *s, rta *a, ip_addr gw, ip_addr ll) +bgp_apply_next_hop(struct bgp_parse_state *s, ea_list **to, ip_addr gw, ip_addr ll) { struct bgp_proto *p = s->proto; struct bgp_channel *c = s->channel; @@ -966,7 +966,7 @@ bgp_apply_next_hop(struct bgp_parse_state *s, rta *a, ip_addr gw, ip_addr ll) if (nbr->scope == SCOPE_HOST) WITHDRAW(BAD_NEXT_HOP " - address %I is local", nbr->addr); - ea_set_attr_u32(&a->eattrs, &ea_gen_igp_metric, 0, c->cf->cost); + ea_set_attr_u32(to, &ea_gen_igp_metric, 0, c->cf->cost); struct nexthop_adata nhad = { .nh = { @@ -977,7 +977,7 @@ bgp_apply_next_hop(struct bgp_parse_state *s, rta *a, ip_addr gw, ip_addr ll) .length = sizeof nhad - sizeof nhad.ad, }, }; - ea_set_attr_data(&a->eattrs, &ea_gen_nexthop, 0, nhad.ad.data, nhad.ad.length); + ea_set_attr_data(to, &ea_gen_nexthop, 0, nhad.ad.data, nhad.ad.length); } else /* GW_RECURSIVE */ { @@ -988,21 +988,21 @@ bgp_apply_next_hop(struct bgp_parse_state *s, rta *a, ip_addr gw, ip_addr ll) if (s->mpls) { u32 labels[BGP_MPLS_MAX]; - ea_set_hostentry(&a->eattrs, c->c.table, tab, gw, ll, BGP_MPLS_MAX, labels); + ea_set_hostentry(to, c->c.table, tab, gw, ll, BGP_MPLS_MAX, labels); } else - ea_set_hostentry(&a->eattrs, c->c.table, tab, gw, ll, 0, NULL); + ea_set_hostentry(to, c->c.table, tab, gw, ll, 0, NULL); } } static void -bgp_apply_mpls_labels(struct bgp_parse_state *s, rta *a, u32 lnum, u32 labels[lnum]) +bgp_apply_mpls_labels(struct bgp_parse_state *s, ea_list **to, u32 lnum, u32 labels[lnum]) { if (lnum > MPLS_MAX_LABEL_STACK) { REPORT("Too many MPLS labels ($u)", lnum); - ea_set_dest(&a->eattrs, 0, RTD_UNREACHABLE); + ea_set_dest(to, 0, RTD_UNREACHABLE); return; } @@ -1012,7 +1012,7 @@ bgp_apply_mpls_labels(struct bgp_parse_state *s, rta *a, u32 lnum, u32 labels[ln if (s->channel->cf->gw_mode == GW_DIRECT) { - eattr *e = ea_find(a->eattrs, &ea_gen_nexthop); + eattr *e = ea_find(*to, &ea_gen_nexthop); struct { struct nexthop_adata nhad; u32 labels[MPLS_MAX_LABEL_STACK]; @@ -1025,7 +1025,7 @@ bgp_apply_mpls_labels(struct bgp_parse_state *s, rta *a, u32 lnum, u32 labels[ln } else /* GW_RECURSIVE */ { - eattr *e = ea_find(a->eattrs, &ea_gen_hostentry); + eattr *e = ea_find(*to, &ea_gen_hostentry); ASSERT_DIE(e); struct hostentry_adata *head = (void *) e->u.ptr; memcpy(&head->labels, labels, lnum * sizeof(u32)); @@ -1034,24 +1034,24 @@ bgp_apply_mpls_labels(struct bgp_parse_state *s, rta *a, u32 lnum, u32 labels[ln } static void -bgp_apply_flow_validation(struct bgp_parse_state *s, const net_addr *n, rta *a) +bgp_apply_flow_validation(struct bgp_parse_state *s, const net_addr *n, ea_list **to) { struct bgp_channel *c = s->channel; - uint valid = rt_flowspec_check(c->base_table, c->c.table, n, a, s->proto->is_interior); + uint valid = rt_flowspec_check(c->base_table, c->c.table, n, *to, s->proto->is_interior); /* Invalidate cached rta */ - if (s->cached_rta) + if (s->cached_ea) { /* Has't changed */ - if (valid == ea_get_int(s->cached_rta->eattrs, &ea_gen_flowspec_valid, FLOWSPEC_UNKNOWN)) + if (valid == ea_get_int(s->cached_ea, &ea_gen_flowspec_valid, FLOWSPEC_UNKNOWN)) return; - rta_free(s->cached_rta); - s->cached_rta = NULL; + rta_free(s->cached_ea); + s->cached_ea = NULL; } /* Set the value */ - ea_set_attr_u32(&a->eattrs, &ea_gen_flowspec_valid, 0, valid); + ea_set_attr_u32(to, &ea_gen_flowspec_valid, 0, valid); } static int @@ -1105,13 +1105,13 @@ bgp_use_gateway(struct bgp_export_state *s) { struct bgp_proto *p = s->proto; struct bgp_channel *c = s->channel; - rta *ra = s->route->attrs; + ea_list *ra = s->route->attrs; /* Handle next hop self option - also applies to gateway */ if (c->cf->next_hop_self && bgp_match_src(s, c->cf->next_hop_self)) return NULL; - eattr *nhea = ea_find(ra->eattrs, &ea_gen_nexthop); + eattr *nhea = ea_find(ra, &ea_gen_nexthop); if (!nhea) return NULL; @@ -1229,7 +1229,7 @@ bgp_encode_next_hop_ip(struct bgp_write_state *s, eattr *a, byte *buf, uint size } static void -bgp_decode_next_hop_ip(struct bgp_parse_state *s, byte *data, uint len, rta *a) +bgp_decode_next_hop_ip(struct bgp_parse_state *s, byte *data, uint len, ea_list **to) { struct bgp_channel *c = s->channel; struct adata *ad = lp_alloc_adata(s->pool, 32); @@ -1270,8 +1270,8 @@ bgp_decode_next_hop_ip(struct bgp_parse_state *s, byte *data, uint len, rta *a) // XXXX validate next hop - bgp_set_attr_ptr(&(a->eattrs), BA_NEXT_HOP, 0, ad); - bgp_apply_next_hop(s, a, nh[0], nh[1]); + bgp_set_attr_ptr(to, BA_NEXT_HOP, 0, ad); + bgp_apply_next_hop(s, to, nh[0], nh[1]); } static uint @@ -1309,7 +1309,7 @@ bgp_encode_next_hop_vpn(struct bgp_write_state *s, eattr *a, byte *buf, uint siz } static void -bgp_decode_next_hop_vpn(struct bgp_parse_state *s, byte *data, uint len, rta *a) +bgp_decode_next_hop_vpn(struct bgp_parse_state *s, byte *data, uint len, ea_list **to) { struct bgp_channel *c = s->channel; struct adata *ad = lp_alloc_adata(s->pool, 32); @@ -1351,8 +1351,8 @@ bgp_decode_next_hop_vpn(struct bgp_parse_state *s, byte *data, uint len, rta *a) // XXXX validate next hop - bgp_set_attr_ptr(&(a->eattrs), BA_NEXT_HOP, 0, ad); - bgp_apply_next_hop(s, a, nh[0], nh[1]); + bgp_set_attr_ptr(to, BA_NEXT_HOP, 0, ad); + bgp_apply_next_hop(s, to, nh[0], nh[1]); } @@ -1364,7 +1364,7 @@ bgp_encode_next_hop_none(struct bgp_write_state *s UNUSED, eattr *a UNUSED, byte } static void -bgp_decode_next_hop_none(struct bgp_parse_state *s UNUSED, byte *data UNUSED, uint len UNUSED, rta *a UNUSED) +bgp_decode_next_hop_none(struct bgp_parse_state *s UNUSED, byte *data UNUSED, uint len UNUSED, ea_list **to UNUSED) { /* * Although we expect no next hop and RFC 7606 7.11 states that attribute @@ -1389,15 +1389,15 @@ bgp_update_next_hop_none(struct bgp_export_state *s UNUSED, eattr *a, ea_list ** */ static void -bgp_rte_update(struct bgp_parse_state *s, const net_addr *n, u32 path_id, rta *a0) +bgp_rte_update(struct bgp_parse_state *s, const net_addr *n, u32 path_id, ea_list *a0) { if (path_id != s->last_id) { s->last_src = rt_get_source(&s->proto->p, path_id); s->last_id = path_id; - rta_free(s->cached_rta); - s->cached_rta = NULL; + ea_free(s->cached_ea); + s->cached_ea = NULL; } if (!a0) @@ -1412,16 +1412,10 @@ bgp_rte_update(struct bgp_parse_state *s, const net_addr *n, u32 path_id, rta *a } /* Prepare cached route attributes */ - if (s->cached_rta == NULL) - { - /* Workaround for rta_lookup() breaking eattrs */ - ea_list *ea = a0->eattrs; - s->cached_rta = rta_lookup(a0); - a0->eattrs = ea; - } + if (s->cached_ea == NULL) + s->cached_ea = ea_lookup(a0); - rta *a = rta_clone(s->cached_rta); - rte *e = rte_get_temp(a, s->last_src); + rte *e = rte_get_temp(rta_clone(s->cached_ea), s->last_src); e->pflags = 0; rte_update3(&s->channel->c, n, e, s->last_src); @@ -1447,7 +1441,7 @@ bgp_encode_mpls_labels(struct bgp_write_state *s UNUSED, const adata *mpls, byte } static void -bgp_decode_mpls_labels(struct bgp_parse_state *s, byte **pos, uint *len, uint *pxlen, rta *a) +bgp_decode_mpls_labels(struct bgp_parse_state *s, byte **pos, uint *len, uint *pxlen, ea_list **to) { u32 labels[BGP_MPLS_MAX]; u32 label; @@ -1469,15 +1463,15 @@ bgp_decode_mpls_labels(struct bgp_parse_state *s, byte **pos, uint *len, uint *p } while (!(label & BGP_MPLS_BOS)); - if (!a) + if (!*to) return; /* Update next hop entry in rta */ - bgp_apply_mpls_labels(s, a, lnum, labels); + bgp_apply_mpls_labels(s, to, lnum, labels); /* Attributes were changed, invalidate cached entry */ - rta_free(s->cached_rta); - s->cached_rta = NULL; + rta_free(s->cached_ea); + s->cached_ea = NULL; return; } @@ -1520,7 +1514,7 @@ bgp_encode_nlri_ip4(struct bgp_write_state *s, struct bgp_bucket *buck, byte *bu } static void -bgp_decode_nlri_ip4(struct bgp_parse_state *s, byte *pos, uint len, rta *a) +bgp_decode_nlri_ip4(struct bgp_parse_state *s, byte *pos, uint len, ea_list *a) { while (len) { @@ -1546,7 +1540,7 @@ bgp_decode_nlri_ip4(struct bgp_parse_state *s, byte *pos, uint len, rta *a) /* Decode MPLS labels */ if (s->mpls) - bgp_decode_mpls_labels(s, &pos, &len, &l, a); + bgp_decode_mpls_labels(s, &pos, &len, &l, &a); if (l > IP4_MAX_PREFIX_LENGTH) bgp_parse_error(s, 10); @@ -1605,7 +1599,7 @@ bgp_encode_nlri_ip6(struct bgp_write_state *s, struct bgp_bucket *buck, byte *bu } static void -bgp_decode_nlri_ip6(struct bgp_parse_state *s, byte *pos, uint len, rta *a) +bgp_decode_nlri_ip6(struct bgp_parse_state *s, byte *pos, uint len, ea_list *a) { while (len) { @@ -1631,7 +1625,7 @@ bgp_decode_nlri_ip6(struct bgp_parse_state *s, byte *pos, uint len, rta *a) /* Decode MPLS labels */ if (s->mpls) - bgp_decode_mpls_labels(s, &pos, &len, &l, a); + bgp_decode_mpls_labels(s, &pos, &len, &l, &a); if (l > IP6_MAX_PREFIX_LENGTH) bgp_parse_error(s, 10); @@ -1693,7 +1687,7 @@ bgp_encode_nlri_vpn4(struct bgp_write_state *s, struct bgp_bucket *buck, byte *b } static void -bgp_decode_nlri_vpn4(struct bgp_parse_state *s, byte *pos, uint len, rta *a) +bgp_decode_nlri_vpn4(struct bgp_parse_state *s, byte *pos, uint len, ea_list *a) { while (len) { @@ -1719,7 +1713,7 @@ bgp_decode_nlri_vpn4(struct bgp_parse_state *s, byte *pos, uint len, rta *a) /* Decode MPLS labels */ if (s->mpls) - bgp_decode_mpls_labels(s, &pos, &len, &l, a); + bgp_decode_mpls_labels(s, &pos, &len, &l, &a); /* Decode route distinguisher */ if (l < 64) @@ -1790,7 +1784,7 @@ bgp_encode_nlri_vpn6(struct bgp_write_state *s, struct bgp_bucket *buck, byte *b } static void -bgp_decode_nlri_vpn6(struct bgp_parse_state *s, byte *pos, uint len, rta *a) +bgp_decode_nlri_vpn6(struct bgp_parse_state *s, byte *pos, uint len, ea_list *a) { while (len) { @@ -1816,7 +1810,7 @@ bgp_decode_nlri_vpn6(struct bgp_parse_state *s, byte *pos, uint len, rta *a) /* Decode MPLS labels */ if (s->mpls) - bgp_decode_mpls_labels(s, &pos, &len, &l, a); + bgp_decode_mpls_labels(s, &pos, &len, &l, &a); /* Decode route distinguisher */ if (l < 64) @@ -1877,7 +1871,7 @@ bgp_encode_nlri_flow4(struct bgp_write_state *s, struct bgp_bucket *buck, byte * } static void -bgp_decode_nlri_flow4(struct bgp_parse_state *s, byte *pos, uint len, rta *a) +bgp_decode_nlri_flow4(struct bgp_parse_state *s, byte *pos, uint len, ea_list *a) { while (len) { @@ -1930,7 +1924,7 @@ bgp_decode_nlri_flow4(struct bgp_parse_state *s, byte *pos, uint len, rta *a) /* Apply validation procedure per RFC 8955 (6) */ if (a && s->channel->cf->validate) - bgp_apply_flow_validation(s, n, a); + bgp_apply_flow_validation(s, n, &a); bgp_rte_update(s, n, path_id, a); } @@ -1969,7 +1963,7 @@ bgp_encode_nlri_flow6(struct bgp_write_state *s, struct bgp_bucket *buck, byte * } static void -bgp_decode_nlri_flow6(struct bgp_parse_state *s, byte *pos, uint len, rta *a) +bgp_decode_nlri_flow6(struct bgp_parse_state *s, byte *pos, uint len, ea_list *a) { while (len) { @@ -2022,7 +2016,7 @@ bgp_decode_nlri_flow6(struct bgp_parse_state *s, byte *pos, uint len, rta *a) /* Apply validation procedure per RFC 8955 (6) */ if (a && s->channel->cf->validate) - bgp_apply_flow_validation(s, n, a); + bgp_apply_flow_validation(s, n, &a); bgp_rte_update(s, n, path_id, a); } @@ -2472,7 +2466,6 @@ static inline void bgp_decode_nlri(struct bgp_parse_state *s, u32 afi, byte *nlri, uint len, ea_list *ea, byte *nh, uint nh_len) { struct bgp_channel *c = bgp_get_channel(s->proto, afi); - rta *a = NULL; if (!c) DISCARD(BAD_AFI, BGP_AFI(afi), BGP_SAFI(afi)); @@ -2493,26 +2486,22 @@ bgp_decode_nlri(struct bgp_parse_state *s, u32 afi, byte *nlri, uint len, ea_lis if (ea) { - a = allocz(RTA_MAX_SIZE); - - a->eattrs = ea; - - ea_set_attr_data(&a->eattrs, &ea_gen_from, 0, &s->proto->remote_ip, sizeof(ip_addr)); - ea_set_attr_u32(&a->eattrs, &ea_gen_preference, 0, c->c.preference); - ea_set_attr_u32(&a->eattrs, &ea_gen_source, 0, RTS_BGP); + ea_set_attr_data(&ea, &ea_gen_from, 0, &s->proto->remote_ip, sizeof(ip_addr)); + ea_set_attr_u32(&ea, &ea_gen_preference, 0, c->c.preference); + ea_set_attr_u32(&ea, &ea_gen_source, 0, RTS_BGP); - c->desc->decode_next_hop(s, nh, nh_len, a); - bgp_finish_attrs(s, a); + c->desc->decode_next_hop(s, nh, nh_len, &ea); + bgp_finish_attrs(s, &ea); /* Handle withdraw during next hop decoding */ if (s->err_withdraw) - a = NULL; + ea = NULL; } - c->desc->decode_nlri(s, nlri, len, a); + c->desc->decode_nlri(s, nlri, len, ea); - rta_free(s->cached_rta); - s->cached_rta = NULL; + rta_free(s->cached_ea); + s->cached_ea = NULL; } static void @@ -2617,7 +2606,7 @@ bgp_rx_update(struct bgp_conn *conn, byte *pkt, uint len) ea, s.mp_next_hop_data, s.mp_next_hop_len); done: - rta_free(s.cached_rta); + rta_free(s.cached_ea); lp_restore(tmp_linpool, &tmpp); return; } diff --git a/proto/mrt/mrt.c b/proto/mrt/mrt.c index e45f7cb7..7b6e7772 100644 --- a/proto/mrt/mrt.c +++ b/proto/mrt/mrt.c @@ -423,7 +423,7 @@ mrt_rib_table_header(struct mrt_table_dump_state *s, net_addr *n) static void mrt_rib_table_entry_bgp_attrs(struct mrt_table_dump_state *s, rte *r) { - struct ea_list *eattrs = r->attrs->eattrs; + struct ea_list *eattrs = r->attrs; buffer *b = &s->buf; if (!eattrs) diff --git a/proto/ospf/ospf.c b/proto/ospf/ospf.c index 731adaa5..87911531 100644 --- a/proto/ospf/ospf.c +++ b/proto/ospf/ospf.c @@ -387,7 +387,7 @@ ospf_init(struct proto_config *CF) static int ospf_rte_better(struct rte *new, struct rte *old) { - u32 new_metric1 = ea_get_int(new->attrs->eattrs, &ea_ospf_metric1, LSINFINITY); + u32 new_metric1 = ea_get_int(new->attrs, &ea_ospf_metric1, LSINFINITY); if (new_metric1 == LSINFINITY) return 0; @@ -400,13 +400,13 @@ ospf_rte_better(struct rte *new, struct rte *old) if (ns == RTS_OSPF_EXT2) { - u32 old_metric2 = ea_get_int(old->attrs->eattrs, &ea_ospf_metric2, LSINFINITY); - u32 new_metric2 = ea_get_int(new->attrs->eattrs, &ea_ospf_metric2, LSINFINITY); + u32 old_metric2 = ea_get_int(old->attrs, &ea_ospf_metric2, LSINFINITY); + u32 new_metric2 = ea_get_int(new->attrs, &ea_ospf_metric2, LSINFINITY); if (new_metric2 < old_metric2) return 1; if (new_metric2 > old_metric2) return 0; } - u32 old_metric1 = ea_get_int(old->attrs->eattrs, &ea_ospf_metric1, LSINFINITY); + u32 old_metric1 = ea_get_int(old->attrs, &ea_ospf_metric1, LSINFINITY); if (new_metric1 < old_metric1) return 1; @@ -419,7 +419,7 @@ ospf_rte_igp_metric(struct rte *rt) if (rt_get_source_attr(rt) == RTS_OSPF_EXT2) return IGP_METRIC_UNKNOWN; - return ea_get_int(rt->attrs->eattrs, &ea_ospf_metric1, LSINFINITY); + return ea_get_int(rt->attrs, &ea_ospf_metric1, LSINFINITY); } void @@ -535,7 +535,7 @@ ospf_shutdown(struct proto *P) /* Cleanup locked rta entries */ FIB_WALK(&p->rtf, ort, nf) { - rta_free(nf->old_rta); + ea_free(nf->old_ea); } FIB_WALK_END; @@ -592,18 +592,18 @@ ospf_get_route_info(rte * rte, byte * buf) } buf += bsprintf(buf, " %s", type); - buf += bsprintf(buf, " (%d/%d", rt_get_preference(rte), ea_get_int(rte->attrs->eattrs, &ea_ospf_metric1, LSINFINITY)); + buf += bsprintf(buf, " (%d/%d", rt_get_preference(rte), ea_get_int(rte->attrs, &ea_ospf_metric1, LSINFINITY)); if (source == RTS_OSPF_EXT2) - buf += bsprintf(buf, "/%d", ea_get_int(rte->attrs->eattrs, &ea_ospf_metric2, LSINFINITY)); + buf += bsprintf(buf, "/%d", ea_get_int(rte->attrs, &ea_ospf_metric2, LSINFINITY)); buf += bsprintf(buf, ")"); if (source == RTS_OSPF_EXT1 || source == RTS_OSPF_EXT2) { - eattr *ea = ea_find(rte->attrs->eattrs, &ea_ospf_tag); + eattr *ea = ea_find(rte->attrs, &ea_ospf_tag); if (ea && (ea->u.data > 0)) buf += bsprintf(buf, " [%x]", ea->u.data); } - eattr *ea = ea_find(rte->attrs->eattrs, &ea_ospf_router_id); + eattr *ea = ea_find(rte->attrs, &ea_ospf_router_id); if (ea) buf += bsprintf(buf, " [%R]", ea->u.data); } diff --git a/proto/ospf/rt.c b/proto/ospf/rt.c index afe4a01f..3889d634 100644 --- a/proto/ospf/rt.c +++ b/proto/ospf/rt.c @@ -1977,17 +1977,17 @@ add_cand(struct ospf_area *oa, struct top_hash_entry *en, struct top_hash_entry } static inline int -ort_changed(ort *nf, rta *nr) +ort_changed(ort *nf, ea_list *nr) { - rta *or = nf->old_rta; + ea_list *or = nf->old_ea; if (!or || (nf->n.metric1 != nf->old_metric1) || (nf->n.metric2 != nf->old_metric2) || (nf->n.tag != nf->old_tag) || (nf->n.rid != nf->old_rid)) return 1; - eattr *nhea_n = ea_find(nr->eattrs, &ea_gen_nexthop); - eattr *nhea_o = ea_find(or->eattrs, &ea_gen_nexthop); + eattr *nhea_n = ea_find(nr, &ea_gen_nexthop); + eattr *nhea_o = ea_find(or, &ea_gen_nexthop); if (!nhea_n != !nhea_o) return 1; @@ -2000,8 +2000,8 @@ ort_changed(ort *nf, rta *nr) return 1; } - if ( ea_get_int(nr->eattrs, &ea_gen_source, 0) - != ea_get_int(or->eattrs, &ea_gen_source, 0)) + if ( ea_get_int(nr, &ea_gen_source, 0) + != ea_get_int(or, &ea_gen_source, 0)) return 1; return 0; @@ -2047,9 +2047,6 @@ again1: if (nf->n.type) /* Add the route */ { - rta a0 = { - }; - struct { ea_list l; eattr a[7]; @@ -2066,7 +2063,7 @@ again1: eattrs.a[eattrs.l.count++] = EA_LITERAL_DIRECT_ADATA(&ea_gen_nexthop, 0, &nf->n.nhs->ad); - if (reload || ort_changed(nf, &a0)) + if (reload || ort_changed(nf, &eattrs.l)) { nf->old_metric1 = nf->n.metric1; nf->old_metric2 = nf->n.metric2; @@ -2088,24 +2085,25 @@ again1: EA_LITERAL_EMBEDDED(&ea_ospf_router_id, 0, nf->n.rid); ASSERT_DIE(ARRAY_SIZE(eattrs.a) >= eattrs.l.count); - a0.eattrs = &eattrs.l; - rta *a = rta_lookup(&a0); + ea_list *a = rta_lookup(&eattrs.l); rte *e = rte_get_temp(a, p->p.main_source); - rta_free(nf->old_rta); - nf->old_rta = rta_clone(a); + rta_free(nf->old_ea); + nf->old_ea = rta_clone(a); + /* 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); } } - else if (nf->old_rta) + else if (nf->old_ea) { /* Remove the route */ - rta_free(nf->old_rta); - nf->old_rta = NULL; + rta_free(nf->old_ea); + nf->old_ea = NULL; rte_update(&p->p, nf->fn.addr, NULL); } diff --git a/proto/ospf/rt.h b/proto/ospf/rt.h index 180216b7..88eefef9 100644 --- a/proto/ospf/rt.h +++ b/proto/ospf/rt.h @@ -78,7 +78,7 @@ typedef struct ort */ orta n; u32 old_metric1, old_metric2, old_tag, old_rid; - rta *old_rta; + ea_list *old_ea; u32 lsa_id; u8 external_rte; u8 area_net; diff --git a/proto/ospf/topology.c b/proto/ospf/topology.c index 09ec9f28..e3dd0885 100644 --- a/proto/ospf/topology.c +++ b/proto/ospf/topology.c @@ -1337,9 +1337,9 @@ ospf_rt_notify(struct proto *P, struct channel *ch UNUSED, net *n, rte *new, rte ASSERT(p->asbr); /* Get route attributes */ - rta *a = new->attrs; - eattr *m1a = ea_find(a->eattrs, &ea_ospf_metric1); - eattr *m2a = ea_find(a->eattrs, &ea_ospf_metric2); + ea_list *a = new->attrs; + eattr *m1a = ea_find(a, &ea_ospf_metric1); + eattr *m2a = ea_find(a, &ea_ospf_metric2); uint m1 = m1a ? m1a->u.data : 0; uint m2 = m2a ? m2a->u.data : 10000; @@ -1363,10 +1363,10 @@ ospf_rt_notify(struct proto *P, struct channel *ch UNUSED, net *n, rte *new, rte uint ebit = m2a || !m1a; uint metric = ebit ? m2 : m1; - uint tag = ea_get_int(a->eattrs, &ea_ospf_tag, 0); + uint tag = ea_get_int(a, &ea_ospf_tag, 0); ip_addr fwd = IPA_NONE; - eattr *nhea = ea_find(a->eattrs, &ea_gen_nexthop); + eattr *nhea = ea_find(a, &ea_gen_nexthop); if (nhea) { struct nexthop_adata *nhad = (struct nexthop_adata *) nhea->u.ptr; diff --git a/proto/perf/perf.c b/proto/perf/perf.c index d1ff6adf..17e4041b 100644 --- a/proto/perf/perf.c +++ b/proto/perf/perf.c @@ -85,7 +85,7 @@ random_net_ip4(void) } struct perf_random_routes { - struct rta *a; + ea_list *a; net_addr net; }; @@ -142,10 +142,10 @@ perf_loop(void *data) *((net_addr_ip4 *) &(p->data[i].net)) = random_net_ip4(); if (!p->attrs_per_rte || !(i % p->attrs_per_rte)) { - struct rta a0 = {}; + ea_list *ea = NULL; - ea_set_attr_u32(&a0.eattrs, &ea_gen_preference, 0, p->p.main_channel->preference); - ea_set_attr_u32(&a0.eattrs, &ea_gen_source, 0, RTS_PERF); + ea_set_attr_u32(&ea, &ea_gen_preference, 0, p->p.main_channel->preference); + ea_set_attr_u32(&ea, &ea_gen_source, 0, RTS_PERF); struct nexthop_adata nhad = { .nh.iface = p->ifa->iface, @@ -153,10 +153,10 @@ perf_loop(void *data) .nh.weight = 1, }; - ea_set_attr_data(&a0.eattrs, &ea_gen_nexthop, 0, + ea_set_attr_data(&ea, &ea_gen_nexthop, 0, &nhad.ad.data, sizeof nhad - sizeof nhad.ad); - p->data[i].a = rta_lookup(&a0); + p->data[i].a = rta_lookup(ea); } else p->data[i].a = rta_clone(p->data[i-1].a); diff --git a/proto/pipe/pipe.c b/proto/pipe/pipe.c index e458a238..bdffed3b 100644 --- a/proto/pipe/pipe.c +++ b/proto/pipe/pipe.c @@ -55,7 +55,6 @@ pipe_rt_notify(struct proto *P, struct channel *src_ch, net *n, rte *new, rte *o struct rte_src *src; rte *e; - rta *a; if (!new && !old) return; @@ -71,11 +70,8 @@ pipe_rt_notify(struct proto *P, struct channel *src_ch, net *n, rte *new, rte *o { src = new->src; - a = alloca(rta_size(new->attrs)); - memcpy(a, new->attrs, rta_size(new->attrs)); - - a->cached = 0; - ea_unset_attr(&a->eattrs, 0, &ea_gen_hostentry); + ea_list *a = new->attrs; + ea_unset_attr(&a, 0, &ea_gen_hostentry); e = rte_get_temp(a, src); e->pflags = new->pflags; diff --git a/proto/radv/radv.c b/proto/radv/radv.c index 5734dbc9..c0715b68 100644 --- a/proto/radv/radv.c +++ b/proto/radv/radv.c @@ -447,11 +447,11 @@ radv_rt_notify(struct proto *P, struct channel *ch UNUSED, net *n, rte *new, rte { /* Update */ - ea = ea_find(new->attrs->eattrs, &ea_radv_preference); + ea = ea_find(new->attrs, &ea_radv_preference); uint preference = ea ? ea->u.data : RA_PREF_MEDIUM; uint preference_set = !!ea; - ea = ea_find(new->attrs->eattrs, &ea_radv_lifetime); + ea = ea_find(new->attrs, &ea_radv_lifetime); uint lifetime = ea ? ea->u.data : 0; uint lifetime_set = !!ea; diff --git a/proto/rip/rip.c b/proto/rip/rip.c index a0f2fdc0..ce452ac7 100644 --- a/proto/rip/rip.c +++ b/proto/rip/rip.c @@ -151,8 +151,6 @@ rip_announce_rte(struct rip_proto *p, struct rip_entry *en) if (rt) { /* Update */ - rta a0 = {}; - struct { ea_list l; eattr a[3]; @@ -164,7 +162,8 @@ rip_announce_rte(struct rip_proto *p, struct rip_entry *en) EA_LITERAL_EMBEDDED(&ea_rip_metric, 0, rt->metric), }, }; - a0.eattrs = &ea_block.l; + + ea_list *ea = &ea_block.l; u16 rt_tag = rt->tag; struct iface *rt_from = NULL; @@ -203,7 +202,7 @@ rip_announce_rte(struct rip_proto *p, struct rip_entry *en) nhad->ad.length = ((void *) nh - (void *) nhad->ad.data); - ea_set_attr(&a0.eattrs, + ea_set_attr(&ea, EA_LITERAL_DIRECT_ADATA(&ea_gen_nexthop, 0, &(nexthop_sort(nhad, tmp_linpool)->ad))); } @@ -217,22 +216,21 @@ rip_announce_rte(struct rip_proto *p, struct rip_entry *en) .nh.iface = rt->from->ifa->iface, }; - ea_set_attr_data(&a0.eattrs, &ea_gen_nexthop, 0, + ea_set_attr_data(&ea, &ea_gen_nexthop, 0, &nhad.ad.data, sizeof nhad - sizeof nhad.ad); - ea_set_attr_data(&a0.eattrs, &ea_gen_from, 0, &rt->from->nbr->addr, sizeof(ip_addr)); + ea_set_attr_data(&ea, &ea_gen_from, 0, &rt->from->nbr->addr, sizeof(ip_addr)); } - ea_set_attr_u32(&a0.eattrs, &ea_rip_tag, 0, rt_tag); + ea_set_attr_u32(&ea, &ea_rip_tag, 0, rt_tag); struct rip_iface_adata riad = { .ad = { .length = sizeof(struct rip_iface_adata) - sizeof(struct adata) }, .iface = rt_from, }; - ea_set_attr(&a0.eattrs, + ea_set_attr(&ea, EA_LITERAL_DIRECT_ADATA(&ea_rip_from, 0, &riad.ad)); - rta *a = rta_lookup(&a0); - rte *e = rte_get_temp(a, p->p.main_source); + rte *e = rte_get_temp(rta_lookup(ea), p->p.main_source); rte_update(&p->p, en->n.addr, e); } @@ -345,9 +343,9 @@ rip_rt_notify(struct proto *P, struct channel *ch UNUSED, struct network *net, s if (new) { /* Update */ - u32 rt_tag = ea_get_int(new->attrs->eattrs, &ea_rip_tag, 0); - u32 rt_metric = ea_get_int(new->attrs->eattrs, &ea_rip_metric, 1); - const eattr *rie = ea_find(new->attrs->eattrs, &ea_rip_from); + u32 rt_tag = ea_get_int(new->attrs, &ea_rip_tag, 0); + u32 rt_metric = ea_get_int(new->attrs, &ea_rip_metric, 1); + const eattr *rie = ea_find(new->attrs, &ea_rip_from); struct iface *rt_from = rie ? ((struct rip_iface_adata *) rie->u.ptr)->iface : NULL; if (rt_metric > p->infinity) @@ -381,7 +379,7 @@ rip_rt_notify(struct proto *P, struct channel *ch UNUSED, struct network *net, s en->tag = rt_tag; en->from = (new->src->proto == P) ? rt_from : NULL; - eattr *nhea = ea_find(new->attrs->eattrs, &ea_gen_nexthop); + eattr *nhea = ea_find(new->attrs, &ea_gen_nexthop); if (nhea) { struct nexthop_adata *nhad = (struct nexthop_adata *) nhea->u.ptr; @@ -1120,8 +1118,8 @@ rip_rte_better(struct rte *new, struct rte *old) ASSERT_DIE(new->src == old->src); struct rip_proto *p = (struct rip_proto *) new->src->proto; - u32 new_metric = ea_get_int(new->attrs->eattrs, &ea_rip_metric, p->infinity); - u32 old_metric = ea_get_int(old->attrs->eattrs, &ea_rip_metric, p->infinity); + u32 new_metric = ea_get_int(new->attrs, &ea_rip_metric, p->infinity); + u32 old_metric = ea_get_int(old->attrs, &ea_rip_metric, p->infinity); return new_metric < old_metric; } @@ -1129,7 +1127,7 @@ rip_rte_better(struct rte *new, struct rte *old) static u32 rip_rte_igp_metric(struct rte *rt) { - return ea_get_int(rt->attrs->eattrs, &ea_rip_metric, IGP_METRIC_UNKNOWN); + return ea_get_int(rt->attrs, &ea_rip_metric, IGP_METRIC_UNKNOWN); } static void @@ -1230,8 +1228,8 @@ static void rip_get_route_info(rte *rte, byte *buf) { struct rip_proto *p = (struct rip_proto *) rte->src->proto; - u32 rt_metric = ea_get_int(rte->attrs->eattrs, &ea_rip_metric, p->infinity); - u32 rt_tag = ea_get_int(rte->attrs->eattrs, &ea_rip_tag, 0); + u32 rt_metric = ea_get_int(rte->attrs, &ea_rip_metric, p->infinity); + u32 rt_tag = ea_get_int(rte->attrs, &ea_rip_tag, 0); buf += bsprintf(buf, " (%d/%d)", rt_get_preference(rte), rt_metric); diff --git a/proto/rpki/rpki.c b/proto/rpki/rpki.c index 4318cbb7..2d36f1fb 100644 --- a/proto/rpki/rpki.c +++ b/proto/rpki/rpki.c @@ -120,13 +120,11 @@ rpki_table_add_roa(struct rpki_cache *cache, struct channel *channel, const net_ { struct rpki_proto *p = cache->p; - rta a0 = {}; + ea_list *ea = NULL; + ea_set_attr_u32(&ea, &ea_gen_preference, 0, channel->preference); + ea_set_attr_u32(&ea, &ea_gen_source, 0, RTS_RPKI); - ea_set_attr_u32(&a0.eattrs, &ea_gen_preference, 0, channel->preference); - ea_set_attr_u32(&a0.eattrs, &ea_gen_source, 0, RTS_RPKI); - - rta *a = rta_lookup(&a0); - rte *e = rte_get_temp(a, p->p.main_source); + rte *e = rte_get_temp(rta_lookup(ea), p->p.main_source); e->pflags = 0; diff --git a/proto/static/static.c b/proto/static/static.c index 806849c4..29285d37 100644 --- a/proto/static/static.c +++ b/proto/static/static.c @@ -53,10 +53,10 @@ static inline struct rte_src * static_get_source(struct static_proto *p, uint i) static void static_announce_rte(struct static_proto *p, struct static_route *r) { - rta *a = allocz(RTA_MAX_SIZE); + ea_list *ea = NULL; struct rte_src *src = static_get_source(p, r->index); - ea_set_attr_u32(&a->eattrs, &ea_gen_preference, 0, p->p.main_channel->preference); - ea_set_attr_u32(&a->eattrs, &ea_gen_source, 0, RTS_STATIC); + ea_set_attr_u32(&ea, &ea_gen_preference, 0, p->p.main_channel->preference); + ea_set_attr_u32(&ea, &ea_gen_source, 0, RTS_STATIC); if (r->dest == RTD_UNICAST) { @@ -92,7 +92,7 @@ static_announce_rte(struct static_proto *p, struct static_route *r) nh = NEXTHOP_NEXT(nh); } - ea_set_attr_data(&a->eattrs, &ea_gen_nexthop, 0, + ea_set_attr_data(&ea, &ea_gen_nexthop, 0, nhad->ad.data, (void *) nh - (void *) nhad->ad.data); } @@ -102,19 +102,19 @@ static_announce_rte(struct static_proto *p, struct static_route *r) u32 *labels = r->mls ? (void *) r->mls->data : NULL; u32 lnum = r->mls ? r->mls->length / sizeof(u32) : 0; - ea_set_hostentry(&a->eattrs, p->p.main_channel->table, tab, + ea_set_hostentry(&ea, p->p.main_channel->table, tab, r->via, IPA_NONE, lnum, labels); } else if (r->dest) - ea_set_dest(&a->eattrs, 0, r->dest); + ea_set_dest(&ea, 0, r->dest); /* Already announced */ if (r->state == SRS_CLEAN) return; /* We skip rta_lookup() here */ - rte *e = rte_get_temp(a, src); + rte *e = rte_get_temp(ea, src); e->pflags = 0; if (r->cmds) @@ -407,16 +407,16 @@ static_reload_routes(struct channel *C) static int static_rte_better(rte *new, rte *old) { - u32 n = ea_get_int(new->attrs->eattrs, &ea_gen_igp_metric, IGP_METRIC_UNKNOWN); - u32 o = ea_get_int(old->attrs->eattrs, &ea_gen_igp_metric, IGP_METRIC_UNKNOWN); + u32 n = ea_get_int(new->attrs, &ea_gen_igp_metric, IGP_METRIC_UNKNOWN); + u32 o = ea_get_int(old->attrs, &ea_gen_igp_metric, IGP_METRIC_UNKNOWN); return n < o; } static int static_rte_mergable(rte *pri, rte *sec) { - u32 a = ea_get_int(pri->attrs->eattrs, &ea_gen_igp_metric, IGP_METRIC_UNKNOWN); - u32 b = ea_get_int(sec->attrs->eattrs, &ea_gen_igp_metric, IGP_METRIC_UNKNOWN); + u32 a = ea_get_int(pri->attrs, &ea_gen_igp_metric, IGP_METRIC_UNKNOWN); + u32 b = ea_get_int(sec->attrs, &ea_gen_igp_metric, IGP_METRIC_UNKNOWN); return a == b; } @@ -710,7 +710,7 @@ static_copy_config(struct proto_config *dest, struct proto_config *src) static void static_get_route_info(rte *rte, byte *buf) { - eattr *a = ea_find(rte->attrs->eattrs, &ea_gen_igp_metric); + eattr *a = ea_find(rte->attrs, &ea_gen_igp_metric); u32 pref = rt_get_preference(rte); if (a) buf += bsprintf(buf, " (%d/%u)", pref, a->u.data); |