summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--filter/f-inst.c26
-rw-r--r--lib/route.h13
-rw-r--r--sysdep/bsd/krt-sock.c11
-rw-r--r--sysdep/linux/netlink.c92
4 files changed, 40 insertions, 102 deletions
diff --git a/filter/f-inst.c b/filter/f-inst.c
index 0d042e37..7b34ef91 100644
--- a/filter/f-inst.c
+++ b/filter/f-inst.c
@@ -696,21 +696,13 @@
DYNAMIC_ATTR;
ARG_TYPE(1, da.type);
{
- struct ea_list *l = tmp_alloc(sizeof(struct ea_list) + sizeof(eattr));
-
- l->next = NULL;
- l->flags = EALF_SORTED;
- l->count = 1;
- l->attrs[0].id = da.ea_code;
- l->attrs[0].flags = 0;
- l->attrs[0].type = da.type;
- l->attrs[0].originated = 1;
- l->attrs[0].fresh = 1;
- l->attrs[0].undef = 0;
+ struct eattr *a;
if (da.type >= EAF_TYPE__MAX)
bug("Unsupported attribute type");
+ f_rta_cow(fs);
+
switch (da.type) {
case T_OPAQUE:
case T_IFACE:
@@ -718,18 +710,18 @@
break;
case T_IP:
- l->attrs[0].u.ptr = tmp_store_adata(&v1.val.ip, sizeof(ip_addr));
+ a = ea_set_attr(fs->eattrs,
+ EA_LITERAL_STORE_ADATA(da.ea_code, da.type, 0, &v1.val.ip, sizeof(ip_addr)));
break;
default:
- l->attrs[0].u = v1.val.bval;
+ a = ea_set_attr(fs->eattrs,
+ EA_LITERAL_GENERIC(da.ea_code, da.type, 0, .u = v1.val.bval));
break;
-
}
- f_rta_cow(fs);
- l->next = *fs->eattrs;
- *fs->eattrs = l;
+ a->originated = 1;
+ a->fresh = 1;
}
}
diff --git a/lib/route.h b/lib/route.h
index ba7bab61..ad3f3fb7 100644
--- a/lib/route.h
+++ b/lib/route.h
@@ -217,10 +217,7 @@ ea_list *ea_normalize(const ea_list *e);
uint ea_list_size(ea_list *);
void ea_list_copy(ea_list *dest, ea_list *src, uint size);
-struct ea_one_attr_list {
- ea_list l;
- eattr a;
-};
+#define EA_LOCAL_LIST(N) struct { ea_list l; eattr a[N]; }
#define EA_LITERAL_EMBEDDED(_id, _type, _flags, _val) ({ \
ASSERT_DIE(_type & EAF_EMBEDDED); \
@@ -243,16 +240,16 @@ struct ea_one_attr_list {
static inline eattr *
ea_set_attr(ea_list **to, eattr a)
{
- struct ea_one_attr_list *ea = tmp_alloc(sizeof(*ea));
- *ea = (struct ea_one_attr_list) {
+ EA_LOCAL_LIST(1) *ea = tmp_alloc(sizeof(*ea));
+ *ea = (typeof(*ea)) {
.l.flags = EALF_SORTED,
.l.count = 1,
.l.next = *to,
- .a = a,
+ .a[0] = a,
};
*to = &ea->l;
- return &ea->a;
+ return &ea->a[0];
}
static inline void
diff --git a/sysdep/bsd/krt-sock.c b/sysdep/bsd/krt-sock.c
index cd449d11..844b9f83 100644
--- a/sysdep/bsd/krt-sock.c
+++ b/sysdep/bsd/krt-sock.c
@@ -583,15 +583,8 @@ krt_read_route(struct ks_msg *msg, struct krt_proto *p, int scan)
e = rte_get_temp(&a);
e->net = net;
- ea_list *ea = alloca(sizeof(ea_list) + 1 * sizeof(eattr));
- *ea = (ea_list) { .count = 1, .next = e->attrs->eattrs };
- e->attrs->eattrs = ea;
-
- ea->attrs[0] = (eattr) {
- .id = EA_KRT_SOURCE,
- .type = T_INT,
- .u.data = src2,
- };
+ ea_set_attr(e->attrs->eattrs,
+ EA_LITERAL_EMBEDDED(EA_KRT_SOURCE, T_INT, 0, src2));
if (scan)
krt_got_route(p, e, src);
diff --git a/sysdep/linux/netlink.c b/sysdep/linux/netlink.c
index a37692d6..81e02b4c 100644
--- a/sysdep/linux/netlink.c
+++ b/sysdep/linux/netlink.c
@@ -1581,21 +1581,22 @@ nl_announce_route(struct nl_parse_state *s)
rte *e = rte_get_temp(s->attrs, s->proto->p.main_source);
e->net = s->net;
- ea_list *ea = alloca(sizeof(ea_list) + 2 * sizeof(eattr));
- *ea = (ea_list) { .count = 2, .next = e->attrs->eattrs };
- e->attrs->eattrs = ea;
-
- ea->attrs[0] = (eattr) {
- .id = EA_KRT_SOURCE,
- .type = T_INT,
- .u.data = s->krt_proto,
- };
- ea->attrs[1] = (eattr) {
- .id = EA_KRT_METRIC,
- .type = T_INT,
- .u.data = s->krt_metric,
+ EA_LOCAL_LIST(2) ea0 = {
+ .l = { .count = 2, .next = e->attrs->eattrs },
+ .a[0] = (eattr) {
+ .id = EA_KRT_SOURCE,
+ .type = T_INT,
+ .u.data = s->krt_proto,
+ },
+ .a[1] = (eattr) {
+ .id = EA_KRT_METRIC,
+ .type = T_INT,
+ .u.data = s->krt_metric,
+ },
};
+ e->attrs->eattrs = &ea0.l;
+
if (s->scan)
krt_got_route(s->proto, e, s->krt_src);
else
@@ -1865,81 +1866,36 @@ nl_parse_route(struct nl_parse_state *s, struct nlmsghdr *h)
#endif
if (i->rtm_scope != def_scope)
- {
- ea_list *ea = lp_alloc(s->pool, sizeof(ea_list) + sizeof(eattr));
- ea->next = ra->eattrs;
- ra->eattrs = ea;
- ea->flags = EALF_SORTED;
- ea->count = 1;
- ea->attrs[0].id = EA_KRT_SCOPE;
- ea->attrs[0].flags = 0;
- ea->attrs[0].type = T_INT;
- ea->attrs[0].u.data = i->rtm_scope;
- }
+ ea_set_attr(&ra->eattrs,
+ EA_LITERAL_EMBEDDED(EA_KRT_SCOPE, T_INT, 0, i->rtm_scope));
if (a[RTA_PREFSRC])
{
ip_addr ps = rta_get_ipa(a[RTA_PREFSRC]);
- ea_list *ea = lp_alloc(s->pool, sizeof(ea_list) + sizeof(eattr));
- ea->next = ra->eattrs;
- ra->eattrs = ea;
- ea->flags = EALF_SORTED;
- ea->count = 1;
- ea->attrs[0].id = EA_KRT_PREFSRC;
- ea->attrs[0].flags = 0;
- ea->attrs[0].type = T_IP;
-
- struct adata *ad = lp_alloc(s->pool, sizeof(struct adata) + sizeof(ps));
- ad->length = sizeof(ps);
- memcpy(ad->data, &ps, sizeof(ps));
-
- ea->attrs[0].u.ptr = ad;
+ ea_set_attr(&ra->eattrs,
+ EA_LITERAL_STORE_ADATA(EA_KRT_PREFSRC, T_IP, 0, &ps, sizeof(ps)));
}
/* Can be set per-route or per-nexthop */
if (s->rta_flow)
- {
- ea_list *ea = lp_alloc(s->pool, sizeof(ea_list) + sizeof(eattr));
- ea->next = ra->eattrs;
- ra->eattrs = ea;
- ea->flags = EALF_SORTED;
- ea->count = 1;
- ea->attrs[0].id = EA_KRT_REALM;
- ea->attrs[0].flags = 0;
- ea->attrs[0].type = T_INT;
- ea->attrs[0].u.data = s->rta_flow;
- }
+ ea_set_attr(&ra->eattrs,
+ EA_LITERAL_EMBEDDED(EA_KRT_REALM, T_INT, 0, s->rta_flow));
if (a[RTA_METRICS])
{
u32 metrics[KRT_METRICS_MAX];
- ea_list *ea = lp_alloc(s->pool, sizeof(ea_list) + KRT_METRICS_MAX * sizeof(eattr));
- int t, n = 0;
-
if (nl_parse_metrics(a[RTA_METRICS], metrics, ARRAY_SIZE(metrics)) < 0)
{
log(L_ERR "KRT: Received route %N with strange RTA_METRICS attribute", net->n.addr);
return;
}
- for (t = 1; t < KRT_METRICS_MAX; t++)
+ for (int t = 1; t < KRT_METRICS_MAX; t++)
if (metrics[0] & (1 << t))
- {
- ea->attrs[n].id = EA_CODE(PROTOCOL_KERNEL, KRT_METRICS_OFFSET + t);
- ea->attrs[n].flags = 0;
- ea->attrs[n].type = T_INT;
- ea->attrs[n].u.data = metrics[t];
- n++;
- }
-
- if (n > 0)
- {
- ea->next = ra->eattrs;
- ea->flags = EALF_SORTED;
- ea->count = n;
- ra->eattrs = ea;
- }
+ ea_set_attr(&ra->eattrs,
+ EA_LITERAL_EMBEDDED(EA_CODE(PROTOCOL_KERNEL, KRT_METRICS_OFFSET + t),
+ T_INT, 0, metrics[t]));
}
/*