summaryrefslogtreecommitdiff
path: root/proto
diff options
context:
space:
mode:
authorMaria Matejka <mq@ucw.cz>2022-05-30 12:03:03 +0200
committerMaria Matejka <mq@ucw.cz>2022-05-30 14:39:09 +0200
commit938742decc6e1d6d3a0375dd012b75172e747bbc (patch)
treea10d9eb2811af43075c2c5272ece7b3dbbb38cdf /proto
parent950775f6fa3d569a9d7cd05e33538d35e895d688 (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.c34
-rw-r--r--proto/bgp/attrs.c66
-rw-r--r--proto/bgp/bgp.h10
-rw-r--r--proto/bgp/packets.c127
-rw-r--r--proto/mrt/mrt.c2
-rw-r--r--proto/ospf/ospf.c20
-rw-r--r--proto/ospf/rt.c32
-rw-r--r--proto/ospf/rt.h2
-rw-r--r--proto/ospf/topology.c10
-rw-r--r--proto/perf/perf.c12
-rw-r--r--proto/pipe/pipe.c8
-rw-r--r--proto/radv/radv.c4
-rw-r--r--proto/rip/rip.c36
-rw-r--r--proto/rpki/rpki.c10
-rw-r--r--proto/static/static.c24
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);