aboutsummaryrefslogtreecommitdiffstats
path: root/nest
diff options
context:
space:
mode:
authorOndrej Zajicek <santiago@crfreenet.org>2023-12-13 17:46:16 +0100
committerOndrej Zajicek <santiago@crfreenet.org>2023-12-13 17:46:16 +0100
commit7d2c7d59a363e690995eb958959f0bc12445355c (patch)
tree135fcbfb1790f6aeef2d05ab368932ff25b2608c /nest
parent2c7555cf2ac8439713dd9148b348128c57222a38 (diff)
downloadbird-7d2c7d59a363e690995eb958959f0bc12445355c.tar.gz
Nest: Fix memory alignment in attribute cache
In attribute cache, adata structures were stored densely in one memory block, without regard to alignment. Let's force at least u32 alignment.
Diffstat (limited to 'nest')
-rw-r--r--nest/route.h1
-rw-r--r--nest/rt-attr.c7
2 files changed, 5 insertions, 3 deletions
diff --git a/nest/route.h b/nest/route.h
index 3e1340fa..d26a4b8c 100644
--- a/nest/route.h
+++ b/nest/route.h
@@ -542,6 +542,7 @@ const char *ea_custom_name(uint ea);
#define EA_ALLOW_UNDEF 0x10000 /* ea_find: allow EAF_TYPE_UNDEF */
#define EA_BIT(n) ((n) << 24) /* Used in bitfield accessors */
#define EA_BIT_GET(ea) ((ea) >> 24)
+#define EA_DATA_ALIGN 4 /* Alignment of adata in attribute cache */
#define EAF_TYPE_MASK 0x1f /* Mask with this to get type */
#define EAF_TYPE_INT 0x01 /* 32-bit unsigned integer number */
diff --git a/nest/rt-attr.c b/nest/rt-attr.c
index 25936d81..7f3645ee 100644
--- a/nest/rt-attr.c
+++ b/nest/rt-attr.c
@@ -766,7 +766,7 @@ ea_list_copy(ea_list *o)
{
eattr *a = &o->attrs[i];
if (!(a->type & EAF_EMBEDDED))
- elen += sizeof(struct adata) + a->u.ptr->length;
+ elen += BIRD_ALIGN(sizeof(struct adata) + a->u.ptr->length, EA_DATA_ALIGN);
}
n = mb_alloc(rta_pool, elen);
@@ -777,11 +777,12 @@ ea_list_copy(ea_list *o)
eattr *a = &n->attrs[i];
if (!(a->type & EAF_EMBEDDED))
{
- unsigned size = sizeof(struct adata) + a->u.ptr->length;
+ uint size_u = sizeof(struct adata) + a->u.ptr->length;
+ uint size = BIRD_ALIGN(size_u, EA_DATA_ALIGN);
ASSERT_DIE(adpos + size <= elen);
struct adata *d = ((void *) n) + adpos;
- memcpy(d, a->u.ptr, size);
+ memcpy(d, a->u.ptr, size_u);
a->u.ptr = d;
adpos += size;