diff options
author | Maria Matejka <mq@ucw.cz> | 2022-03-26 11:56:02 +0100 |
---|---|---|
committer | Maria Matejka <mq@ucw.cz> | 2022-05-04 15:37:41 +0200 |
commit | 0d0f6554a5c233bf2bf830ae319191c4b1808d49 (patch) | |
tree | b90790a9450dc4eaefd1cab522d49221d358a5d9 /nest | |
parent | 80272d4b64a38ee6f04a1c4e8566cac3a2293176 (diff) |
Unified attribute and filter types
This commit removes the EAF_TYPE_* namespace completely and also for
route attributes, filter-based types T_* are used. This simplifies
fetching and setting route attributes from filters.
Also, there is now union bval which serves as an universal value holder
instead of private unions held separately by eattr and filter code.
Diffstat (limited to 'nest')
-rw-r--r-- | nest/config.Y | 2 | ||||
-rw-r--r-- | nest/route.h | 47 | ||||
-rw-r--r-- | nest/rt-attr.c | 23 |
3 files changed, 27 insertions, 45 deletions
diff --git a/nest/config.Y b/nest/config.Y index 92a80589..b597b332 100644 --- a/nest/config.Y +++ b/nest/config.Y @@ -921,7 +921,7 @@ proto_patt2: | TEXT { $$.ptr = $1; $$.patt = 1; } ; -dynamic_attr: IGP_METRIC { $$ = f_new_dynamic_attr(EAF_TYPE_INT, T_INT, EA_GEN_IGP_METRIC); } ; +dynamic_attr: IGP_METRIC { $$ = f_new_dynamic_attr(T_INT, EA_GEN_IGP_METRIC); } ; CF_CODE diff --git a/nest/route.h b/nest/route.h index d2f60f41..da8c723f 100644 --- a/nest/route.h +++ b/nest/route.h @@ -13,6 +13,7 @@ #include "lib/bitmap.h" #include "lib/resource.h" #include "lib/net.h" +#include "lib/type.h" struct ea_list; struct protocol; @@ -506,10 +507,8 @@ typedef struct eattr { byte originated:1; /* The attribute has originated locally */ byte fresh:1; /* An uncached attribute (e.g. modified in export filter) */ byte undef:1; /* Explicitly undefined */ - union { - uintptr_t data; - const struct adata *ptr; /* Attribute data elsewhere */ - } u; + + union bval u; } eattr; @@ -530,22 +529,6 @@ const char *ea_custom_name(uint ea); #define EA_BIT(n) ((n) << 24) /* Used in bitfield accessors */ #define EA_BIT_GET(ea) ((ea) >> 24) -#define EAF_TYPE_MASK 0x1f /* Mask with this to get type */ -#define EAF_TYPE_INT 0x01 /* 32-bit unsigned integer number */ -#define EAF_TYPE_OPAQUE 0x02 /* Opaque byte string (not filterable) */ -#define EAF_TYPE_IP_ADDRESS 0x04 /* IP address */ -#define EAF_TYPE_ROUTER_ID 0x05 /* Router ID (IPv4 address) */ -#define EAF_TYPE_AS_PATH 0x06 /* BGP AS path (encoding per RFC 1771:4.3) */ -#define EAF_TYPE_INT_SET 0x0a /* Set of u32's (e.g., a community list) */ -#define EAF_TYPE_EC_SET 0x0e /* Set of pairs of u32's - ext. community list */ -#define EAF_TYPE_LC_SET 0x08 /* Set of triplets of u32's - large community list */ -#define EAF_TYPE_IFACE 0x0c /* Interface pointer stored in adata */ -#define EAF_TYPE_BGP_ORIGIN 0x11 /* BGP Origin enum */ -#define EAF_TYPE_RA_PREFERENCE 0x13 /* RA Preference enum */ - -#define EAF_EMBEDDED 0x01 /* Data stored in eattr.u.data (part of type spec) */ - /* Otherwise, attribute data is adata */ - typedef struct adata { uint length; /* Length of data */ byte data[0]; @@ -591,7 +574,7 @@ struct ea_walk_state { eattr *ea_find(ea_list *, unsigned ea); eattr *ea_walk(struct ea_walk_state *s, uint id, uint max); -uintptr_t ea_get_int(ea_list *, unsigned ea, uintptr_t def); +u32 ea_get_int(ea_list *, unsigned ea, u32 def); void ea_dump(ea_list *); void ea_sort(ea_list *); /* Sort entries in all sub-lists */ unsigned ea_scan(ea_list *); /* How many bytes do we need for merged ea_list */ @@ -618,7 +601,7 @@ struct ea_one_attr_list { }; static inline eattr * -ea_set_attr(ea_list **to, struct linpool *pool, uint id, uint flags, uint type, uintptr_t val) +ea_set_attr(ea_list **to, struct linpool *pool, uint id, uint flags, uint type, union bval val) { struct ea_one_attr_list *ea = lp_alloc(pool, sizeof(*ea)); *ea = (struct ea_one_attr_list) { @@ -631,11 +614,7 @@ ea_set_attr(ea_list **to, struct linpool *pool, uint id, uint flags, uint type, .a.flags = flags, }; - if (type & EAF_EMBEDDED) - ea->a.u.data = val; - else - ea->a.u.ptr = (struct adata *) val; - + ea->a.u = val; *to = &ea->l; return &ea->a; @@ -659,19 +638,19 @@ ea_unset_attr(ea_list **to, struct linpool *pool, _Bool local, uint code) } static inline void -ea_set_attr_u32(ea_list **to, struct linpool *pool, uint id, uint flags, uint type, u32 val) -{ ea_set_attr(to, pool, id, flags, type, (uintptr_t) val); } - -static inline void -ea_set_attr_ptr(ea_list **to, struct linpool *pool, uint id, uint flags, uint type, struct adata *val) -{ ea_set_attr(to, pool, id, flags, type, (uintptr_t) val); } +ea_set_attr_u32(ea_list **to, struct linpool *pool, uint id, uint flags, uint type, u32 data) +{ + union bval bv = { .data = data }; + ea_set_attr(to, pool, id, flags, type, bv); +} static inline void ea_set_attr_data(ea_list **to, struct linpool *pool, uint id, uint flags, uint type, void *data, uint len) { struct adata *a = lp_alloc_adata(pool, len); memcpy(a->data, data, len); - ea_set_attr(to, pool, id, flags, type, (uintptr_t) a); + union bval bv = { .ptr = a, }; + ea_set_attr(to, pool, id, flags, type, bv); } diff --git a/nest/rt-attr.c b/nest/rt-attr.c index 25548dca..de45dfa1 100644 --- a/nest/rt-attr.c +++ b/nest/rt-attr.c @@ -539,8 +539,8 @@ ea_walk(struct ea_walk_state *s, uint id, uint max) * by calling ea_find() to find the attribute, extracting its value or returning * a provided default if no such attribute is present. */ -uintptr_t -ea_get_int(ea_list *e, unsigned id, uintptr_t def) +u32 +ea_get_int(ea_list *e, unsigned id, u32 def) { eattr *a = ea_find(e, id); if (!a) @@ -950,30 +950,33 @@ ea_show(struct cli *c, const eattr *e) else switch (e->type) { - case EAF_TYPE_INT: + case T_INT: bsprintf(pos, "%u", e->u.data); break; - case EAF_TYPE_OPAQUE: + case T_OPAQUE: opaque_format(ad, pos, end - pos); break; - case EAF_TYPE_IP_ADDRESS: + case T_IP: bsprintf(pos, "%I", *(ip_addr *) ad->data); break; - case EAF_TYPE_ROUTER_ID: + case T_QUAD: bsprintf(pos, "%R", e->u.data); break; - case EAF_TYPE_AS_PATH: + case T_PATH: as_path_format(ad, pos, end - pos); break; - case EAF_TYPE_INT_SET: + case T_CLIST: ea_show_int_set(c, ad, 1, pos, buf, end); return; - case EAF_TYPE_EC_SET: + case T_ECLIST: ea_show_ec_set(c, ad, pos, buf, end); return; - case EAF_TYPE_LC_SET: + case T_LCLIST: ea_show_lc_set(c, ad, pos, buf, end); return; + case T_IFACE: + bsprintf(pos, "%s", ((struct iface *) e->u.ptr)->name); + return; default: bsprintf(pos, "<type %02x>", e->type); } |