summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOndrej Zajicek (work) <santiago@crfreenet.org>2016-11-15 16:24:39 +0100
committerOndrej Zajicek (work) <santiago@crfreenet.org>2016-11-15 16:24:39 +0100
commit261816b0d4f3d4549a4402b95541b82fc7f10a4b (patch)
tree45fe0676d36e099c02cb44202bddd0bba6875da2
parentc8cafc8ebb5320ac7c6117c17e6460036f0fdf62 (diff)
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.
-rw-r--r--nest/a-set.c23
-rw-r--r--nest/attrs.h1
-rw-r--r--proto/bgp/attrs.c2
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