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,20 +1581,21 @@ 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_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, + }, + }; - 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, - }; + e->attrs->eattrs = &ea0.l; if (s->scan) krt_got_route(s->proto, e, s->krt_src); @@ -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])); } /*