summaryrefslogtreecommitdiff
path: root/nest/route.h
diff options
context:
space:
mode:
authorMaria Matejka <mq@ucw.cz>2022-03-14 11:13:48 +0100
committerMaria Matejka <mq@ucw.cz>2022-04-06 18:14:08 +0200
commit0f68515263e91dd49b2d845cdff35af40c064dc2 (patch)
tree8ae7a4859016173a191bd38e8d4aab160dc49825 /nest/route.h
parent63cf5d5d8c8e156a1f427614c8017ca71c32191c (diff)
Unsetting route attributes without messing with type system
Diffstat (limited to 'nest/route.h')
-rw-r--r--nest/route.h51
1 files changed, 37 insertions, 14 deletions
diff --git a/nest/route.h b/nest/route.h
index 9fbac898..bf25dcf9 100644
--- a/nest/route.h
+++ b/nest/route.h
@@ -505,6 +505,7 @@ typedef struct eattr {
byte type:5; /* Attribute type */
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 */
@@ -540,7 +541,6 @@ const char *ea_custom_name(uint ea);
#define EAF_TYPE_PTR 0x0d /* Pointer to an object */
#define EAF_TYPE_EC_SET 0x0e /* Set of pairs of u32's - ext. community list */
#define EAF_TYPE_LC_SET 0x12 /* Set of triplets of u32's - large community list */
-#define EAF_TYPE_UNDEF 0x1f /* `force undefined' entry */
#define EAF_EMBEDDED 0x01 /* Data stored in eattr.u.data (part of type spec) */
#define EAF_VAR_LENGTH 0x02 /* Attribute length is variable (part of type spec) */
@@ -610,27 +610,50 @@ void ea_format_bitfield(const struct eattr *a, byte *buf, int bufsize, const cha
ea = NULL; \
} while(0) \
+struct ea_one_attr_list {
+ ea_list l;
+ eattr a;
+};
+
static inline eattr *
ea_set_attr(ea_list **to, struct linpool *pool, uint id, uint flags, uint type, uintptr_t val)
{
- ea_list *a = lp_alloc(pool, sizeof(ea_list) + sizeof(eattr));
- eattr *e = &a->attrs[0];
+ struct ea_one_attr_list *ea = lp_alloc(pool, sizeof(*ea));
+ *ea = (struct ea_one_attr_list) {
+ .l.flags = EALF_SORTED,
+ .l.count = 1,
+ .l.next = *to,
- a->flags = EALF_SORTED;
- a->count = 1;
- a->next = *to;
- *to = a;
-
- e->id = id;
- e->type = type;
- e->flags = flags;
+ .a.id = id,
+ .a.type = type,
+ .a.flags = flags,
+ };
if (type & EAF_EMBEDDED)
- e->u.data = (u32) val;
+ ea->a.u.data = val;
else
- e->u.ptr = (struct adata *) val;
+ ea->a.u.ptr = (struct adata *) val;
+
+ *to = &ea->l;
- return e;
+ return &ea->a;
+}
+
+static inline void
+ea_unset_attr(ea_list **to, struct linpool *pool, _Bool local, uint code)
+{
+ struct ea_one_attr_list *ea = lp_alloc(pool, sizeof(*ea));
+ *ea = (struct ea_one_attr_list) {
+ .l.flags = EALF_SORTED,
+ .l.count = 1,
+ .l.next = *to,
+ .a.id = code,
+ .a.fresh = local,
+ .a.originated = local,
+ .a.undef = 1,
+ };
+
+ *to = &ea->l;
}
static inline void