From 261816b0d4f3d4549a4402b95541b82fc7f10a4b Mon Sep 17 00:00:00 2001 From: "Ondrej Zajicek (work)" Date: Tue, 15 Nov 2016 16:24:39 +0100 Subject: [PATCH] BGP: Cluster list item should be prepended Commit 3c09af41... changed behavior of int_set_add() from prepend to append, which makes more sense for community list, but prepend must be used for cluster list. Add int_set_prepend() and use it in cluster list handling code. --- nest/a-set.c | 23 +++++++++++++++++++++-- nest/attrs.h | 1 + proto/bgp/attrs.c | 2 +- 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/nest/a-set.c b/nest/a-set.c index bd244e2e..a6c07f45 100644 --- a/nest/a-set.c +++ b/nest/a-set.c @@ -231,6 +231,26 @@ lc_set_contains(struct adata *list, lcomm val) return 0; } +struct adata * +int_set_prepend(struct linpool *pool, struct adata *list, u32 val) +{ + struct adata *res; + int len; + + if (int_set_contains(list, val)) + return list; + + len = list ? list->length : 0; + res = lp_alloc(pool, sizeof(struct adata) + len + 4); + res->length = len + 4; + + if (list) + memcpy(res->data + 4, list->data, list->length); + + * (u32 *) res->data = val; + + return res; +} struct adata * int_set_add(struct linpool *pool, struct adata *list, u32 val) @@ -248,8 +268,7 @@ int_set_add(struct linpool *pool, struct adata *list, u32 val) if (list) memcpy(res->data, list->data, list->length); - u32 *c = (u32 *) (res->data + len); - *c = val; + * (u32 *) (res->data + len) = val; return res; } diff --git a/nest/attrs.h b/nest/attrs.h index 548d71a9..a34e64d3 100644 --- a/nest/attrs.h +++ b/nest/attrs.h @@ -132,6 +132,7 @@ int lc_set_format(struct adata *set, int from, byte *buf, uint size); int int_set_contains(struct adata *list, u32 val); int ec_set_contains(struct adata *list, u64 val); int lc_set_contains(struct adata *list, lcomm val); +struct adata *int_set_prepend(struct linpool *pool, struct adata *list, u32 val); struct adata *int_set_add(struct linpool *pool, struct adata *list, u32 val); struct adata *ec_set_add(struct linpool *pool, struct adata *list, u64 val); struct adata *lc_set_add(struct linpool *pool, struct adata *list, lcomm val); diff --git a/proto/bgp/attrs.c b/proto/bgp/attrs.c index 0309c1f7..aa2a3b46 100644 --- a/proto/bgp/attrs.c +++ b/proto/bgp/attrs.c @@ -1077,7 +1077,7 @@ static inline void bgp_cluster_list_prepend(rte *e, ea_list **attrs, struct linpool *pool, u32 cid) { eattr *a = ea_find(e->attrs->eattrs, EA_CODE(EAP_BGP, BA_CLUSTER_LIST)); - bgp_attach_attr(attrs, pool, BA_CLUSTER_LIST, (uintptr_t) int_set_add(pool, a ? a->u.ptr : NULL, cid)); + bgp_attach_attr(attrs, pool, BA_CLUSTER_LIST, (uintptr_t) int_set_prepend(pool, a ? a->u.ptr : NULL, cid)); } static int