diff options
author | Maria Matejka <mq@ucw.cz> | 2022-06-28 10:51:00 +0200 |
---|---|---|
committer | Maria Matejka <mq@ucw.cz> | 2022-07-11 16:07:09 +0200 |
commit | fd72c696784ba74e793db1fb7c44668c47a383b2 (patch) | |
tree | a7bf6725f33e44c3c2dd6d2191b1afce03a6ec53 /lib | |
parent | dc720a085f0f805891eb086bf96dac99c8a1b7da (diff) |
Attribute lists split to storage headers and data to save BGP memory
Diffstat (limited to 'lib')
-rw-r--r-- | lib/route.h | 29 |
1 files changed, 21 insertions, 8 deletions
diff --git a/lib/route.h b/lib/route.h index 130465f9..30be7c4e 100644 --- a/lib/route.h +++ b/lib/route.h @@ -147,10 +147,6 @@ typedef struct eattr { #define EA_BIT_GET(ea) ((ea) >> 24) typedef struct ea_list { - struct ea_list *next_hash; /* Next in hash chain */ - struct ea_list **pprev_hash; /* Previous in hash chain */ - u32 uc; /* Use count */ - u32 hash_key; /* List hash */ struct ea_list *next; /* In case we have an override list */ byte flags; /* Flags: EALF_... */ byte rfu; @@ -158,10 +154,17 @@ typedef struct ea_list { eattr attrs[0]; /* Attribute definitions themselves */ } ea_list; +struct ea_storage { + struct ea_storage *next_hash; /* Next in hash chain */ + struct ea_storage **pprev_hash; /* Previous in hash chain */ + u32 uc; /* Use count */ + u32 hash_key; /* List hash */ + ea_list l[0]; /* The list itself */ +}; + #define EALF_SORTED 1 /* Attributes are sorted by code */ #define EALF_BISECT 2 /* Use interval bisection for searching */ #define EALF_CACHED 4 /* List is cached */ -#define EALF_OVERLAY 8 /* List is an overlay in the same table */ struct ea_class { #define EA_CLASS_INSIDE \ @@ -417,9 +420,19 @@ static inline int rte_dest(const rte *r) void rta_init(void); ea_list *ea_lookup(ea_list *, int overlay); /* Get a cached (and normalized) variant of this attribute list */ static inline int ea_is_cached(const ea_list *r) { return r->flags & EALF_CACHED; } -static inline ea_list *ea_clone(ea_list *r) { r->uc++; return r; } -void ea__free(ea_list *r); -static inline void ea_free(ea_list *r) { if (r && !--r->uc) ea__free(r); } +static inline struct ea_storage *ea_get_storage(ea_list *r) +{ + ASSERT_DIE(ea_is_cached(r)); + return SKIP_BACK(struct ea_storage, l, r); +} + +static inline ea_list *ea_clone(ea_list *r) { ea_get_storage(r)->uc++; return r; } +void ea__free(struct ea_storage *r); +static inline void ea_free(ea_list *l) { + if (!l) return; + struct ea_storage *r = ea_get_storage(l); + if (!--r->uc) ea__free(r); +} void ea_dump(ea_list *); void ea_dump_all(void); |