summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLouis Scalbert <louis.scalbert@6wind.com>2024-02-23 15:18:03 +0100
committerLouis Scalbert <louis.scalbert@6wind.com>2024-06-05 13:11:29 +0200
commit3c86f776f053bc9032da8dc3b713f7726117b800 (patch)
tree1a728c669fc3437805cf980624721a710fd02879
parenttopotests: add bgp test to check the ADJ-RIB-IN label value (diff)
downloadfrr-3c86f776f053bc9032da8dc3b713f7726117b800.tar.xz
frr-3c86f776f053bc9032da8dc3b713f7726117b800.zip
bgpd: add bgp_labels hash
Add bgp_labels type and hash list. Signed-off-by: Louis Scalbert <louis.scalbert@6wind.com>
-rw-r--r--bgpd/bgp_label.c119
-rw-r--r--bgpd/bgp_label.h15
-rw-r--r--bgpd/bgp_main.c3
-rw-r--r--bgpd/bgp_memory.c2
-rw-r--r--bgpd/bgp_memory.h2
-rw-r--r--bgpd/bgpd.c1
-rw-r--r--tests/bgpd/test_mp_attr.c2
-rw-r--r--tests/bgpd/test_peer_attr.c2
8 files changed, 146 insertions, 0 deletions
diff --git a/bgpd/bgp_label.c b/bgpd/bgp_label.c
index edd3a35e8..f967638de 100644
--- a/bgpd/bgp_label.c
+++ b/bgpd/bgp_label.c
@@ -15,6 +15,7 @@
#include "memory.h"
#include "nexthop.h"
#include "mpls.h"
+#include "jhash.h"
#include "bgpd/bgpd.h"
#include "bgpd/bgp_table.h"
@@ -27,6 +28,124 @@
extern struct zclient *zclient;
+
+/* MPLS Labels hash routines. */
+static struct hash *labels_hash;
+
+static void *bgp_labels_hash_alloc(void *p)
+{
+ const struct bgp_labels *labels = p;
+ struct bgp_labels *new;
+ uint8_t i;
+
+ new = XMALLOC(MTYPE_BGP_LABELS, sizeof(struct bgp_labels));
+
+ new->num_labels = labels->num_labels;
+ for (i = 0; i < labels->num_labels; i++)
+ new->label[i] = labels->label[i];
+
+ return new;
+}
+
+static uint32_t bgp_labels_hash_key_make(const void *p)
+{
+ const struct bgp_labels *labels = p;
+ uint32_t key = 0;
+
+ if (labels->num_labels)
+ key = jhash(&labels->label,
+ labels->num_labels * sizeof(mpls_label_t), key);
+
+ return key;
+}
+
+static bool bgp_labels_hash_cmp(const void *p1, const void *p2)
+{
+ return bgp_labels_cmp(p1, p2);
+}
+
+void bgp_labels_init(void)
+{
+ labels_hash = hash_create(bgp_labels_hash_key_make, bgp_labels_hash_cmp,
+ "BGP Labels hash");
+}
+
+/*
+ * special for hash_clean below
+ */
+static void bgp_labels_free(void *labels)
+{
+ XFREE(MTYPE_BGP_LABELS, labels);
+}
+
+void bgp_labels_finish(void)
+{
+ hash_clean_and_free(&labels_hash, bgp_labels_free);
+}
+
+struct bgp_labels *bgp_labels_intern(struct bgp_labels *labels)
+{
+ struct bgp_labels *find;
+
+ if (!labels)
+ return NULL;
+
+ if (!labels->num_labels)
+ /* do not intern void labels structure */
+ return NULL;
+
+ find = (struct bgp_labels *)hash_get(labels_hash, labels,
+ bgp_labels_hash_alloc);
+ find->refcnt++;
+
+ return find;
+}
+
+void bgp_labels_unintern(struct bgp_labels **plabels)
+{
+ struct bgp_labels *labels = *plabels;
+ struct bgp_labels *ret;
+
+ if (!*plabels)
+ return;
+
+ /* Decrement labels reference. */
+ labels->refcnt--;
+
+ /* If reference becomes zero then free labels object. */
+ if (labels->refcnt == 0) {
+ ret = hash_release(labels_hash, labels);
+ assert(ret != NULL);
+ bgp_labels_free(labels);
+ *plabels = NULL;
+ }
+}
+
+bool bgp_labels_cmp(const struct bgp_labels *labels1,
+ const struct bgp_labels *labels2)
+{
+ uint8_t i;
+
+ if (!labels1 && !labels2)
+ return true;
+
+ if (!labels1 && labels2)
+ return false;
+
+ if (labels1 && !labels2)
+ return false;
+
+ if (labels1->num_labels != labels2->num_labels)
+ return false;
+
+ for (i = 0; i < labels1->num_labels; i++) {
+ if (labels1->label[i] != labels2->label[i])
+ return false;
+ }
+
+ return true;
+}
+
int bgp_parse_fec_update(void)
{
struct stream *s;
diff --git a/bgpd/bgp_label.h b/bgpd/bgp_label.h
index 704d1b495..ecb8dd354 100644
--- a/bgpd/bgp_label.h
+++ b/bgpd/bgp_label.h
@@ -15,6 +15,21 @@ struct bgp_dest;
struct bgp_path_info;
struct peer;
+/* MPLS label(s) - VNI(s) for EVPN-VxLAN */
+struct bgp_labels {
+ mpls_label_t label[BGP_MAX_LABELS];
+ uint8_t num_labels;
+
+ unsigned long refcnt;
+};
+
+extern void bgp_labels_init(void);
+extern void bgp_labels_finish(void);
+extern struct bgp_labels *bgp_labels_intern(struct bgp_labels *labels);
+extern void bgp_labels_unintern(struct bgp_labels **plabels);
+extern bool bgp_labels_cmp(const struct bgp_labels *labels1,
+ const struct bgp_labels *labels2);
+
extern int bgp_reg_for_label_callback(mpls_label_t new_label, void *labelid,
bool allocated);
extern void bgp_reg_dereg_for_label(struct bgp_dest *dest,
diff --git a/bgpd/bgp_main.c b/bgpd/bgp_main.c
index 2bbd3a4b1..97658d340 100644
--- a/bgpd/bgp_main.c
+++ b/bgpd/bgp_main.c
@@ -225,6 +225,9 @@ static __attribute__((__noreturn__)) void bgp_exit(int status)
/* reverse bgp_attr_init */
bgp_attr_finish();
+ /* reverse bgp_labels_init */
+ bgp_labels_finish();
+
/* stop pthreads */
bgp_pthreads_finish();
diff --git a/bgpd/bgp_memory.c b/bgpd/bgp_memory.c
index 53c03d810..c1804fb70 100644
--- a/bgpd/bgp_memory.c
+++ b/bgpd/bgp_memory.c
@@ -102,6 +102,8 @@ DEFINE_MTYPE(BGPD, BGP_FILTER_NAME, "BGP Filter Information");
DEFINE_MTYPE(BGPD, BGP_DUMP_STR, "BGP Dump String Information");
DEFINE_MTYPE(BGPD, ENCAP_TLV, "ENCAP TLV");
+DEFINE_MTYPE(BGPD, BGP_LABELS, "BGP LABELS");
+
DEFINE_MTYPE(BGPD, BGP_TEA_OPTIONS, "BGP TEA Options");
DEFINE_MTYPE(BGPD, BGP_TEA_OPTIONS_VALUE, "BGP TEA Options Value");
diff --git a/bgpd/bgp_memory.h b/bgpd/bgp_memory.h
index 865c5880d..4ae49a2c1 100644
--- a/bgpd/bgp_memory.h
+++ b/bgpd/bgp_memory.h
@@ -98,6 +98,8 @@ DECLARE_MTYPE(BGP_FILTER_NAME);
DECLARE_MTYPE(BGP_DUMP_STR);
DECLARE_MTYPE(ENCAP_TLV);
+DECLARE_MTYPE(BGP_LABELS);
+
DECLARE_MTYPE(BGP_TEA_OPTIONS);
DECLARE_MTYPE(BGP_TEA_OPTIONS_VALUE);
diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c
index d8eba0ab2..2e69b3fc3 100644
--- a/bgpd/bgpd.c
+++ b/bgpd/bgpd.c
@@ -8547,6 +8547,7 @@ void bgp_init(unsigned short instance)
/* BGP inits. */
bgp_attr_init();
+ bgp_labels_init();
bgp_debug_init();
bgp_community_alias_init();
bgp_dump_init();
diff --git a/tests/bgpd/test_mp_attr.c b/tests/bgpd/test_mp_attr.c
index cebdda9e5..44a210403 100644
--- a/tests/bgpd/test_mp_attr.c
+++ b/tests/bgpd/test_mp_attr.c
@@ -23,6 +23,7 @@
#include "bgpd/bgp_nexthop.h"
#include "bgpd/bgp_vty.h"
#include "bgpd/bgp_network.h"
+#include "bgpd/bgp_label.h"
#define VT100_RESET "\x1b[0m"
#define VT100_RED "\x1b[31m"
@@ -1075,6 +1076,7 @@ int main(void)
vrf_init(NULL, NULL, NULL, NULL);
bgp_option_set(BGP_OPT_NO_LISTEN);
bgp_attr_init();
+ bgp_labels_init();
if (fileno(stdout) >= 0)
tty = isatty(fileno(stdout));
diff --git a/tests/bgpd/test_peer_attr.c b/tests/bgpd/test_peer_attr.c
index 12c2f1103..767c41cfe 100644
--- a/tests/bgpd/test_peer_attr.c
+++ b/tests/bgpd/test_peer_attr.c
@@ -18,6 +18,7 @@
#include "bgpd/bgp_vty.h"
#include "bgpd/bgp_zebra.h"
#include "bgpd/bgp_network.h"
+#include "bgpd/bgp_label.h"
#ifdef ENABLE_BGP_VNC
#include "bgpd/rfapi/rfapi_backend.h"
@@ -1374,6 +1375,7 @@ static void bgp_shutdown(void)
bgp_route_finish();
bgp_route_map_terminate();
bgp_attr_finish();
+ bgp_labels_finish();
bgp_pthreads_finish();
access_list_add_hook(NULL);
access_list_delete_hook(NULL);