From 14c1a7bf91f39b72d60df322518bfc48114798b6 Mon Sep 17 00:00:00 2001 From: vivek Date: Mon, 15 May 2017 14:27:51 -0700 Subject: [PATCH] bgpd: EVPN initialization and cleanup Define the EVPN (EVI) hash table and related structures and initialize and cleanup. Signed-off-by: Vivek Venkatraman Reviewed-by: Donald Sharp --- bgpd/bgp_evpn.c | 127 ++++++++++++++++++++++++++++++++++++++++++++++++ bgpd/bgp_evpn.h | 6 +++ bgpd/bgpd.c | 4 ++ bgpd/bgpd.h | 15 ++++++ 4 files changed, 152 insertions(+) diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c index 34a3315c0c..6e6e696a9a 100644 --- a/bgpd/bgp_evpn.c +++ b/bgpd/bgp_evpn.c @@ -26,6 +26,9 @@ #include "log.h" #include "memory.h" #include "stream.h" +#include "hash.h" +#include "jhash.h" +#include "bitfield.h" #include "bgpd/bgp_attr_evpn.h" #include "bgpd/bgpd.h" @@ -35,6 +38,92 @@ #include "bgpd/bgp_mplsvpn.h" #include "bgpd/bgp_label.h" #include "bgpd/bgp_evpn.h" +#include "bgpd/bgp_evpn_private.h" +#include "bgpd/bgp_ecommunity.h" + +/* + * Private functions. + */ + +/* + * Make vni hash key. + */ +static unsigned int +vni_hash_key_make(void *p) +{ + struct bgpevpn *vpn = p; + return (jhash_1word(vpn->vni, 0)); +} + +/* + * Comparison function for vni hash + */ +static int +vni_hash_cmp (const void *p1, const void *p2) +{ + const struct bgpevpn *vpn1 = p1; + const struct bgpevpn *vpn2 = p2; + + if (!vpn1 && !vpn2) + return 1; + if (!vpn1 || !vpn2) + return 0; + return(vpn1->vni == vpn2->vni); +} + +/* + * Make import route target hash key. + */ +static unsigned int +import_rt_hash_key_make (void *p) +{ + struct irt_node *irt = p; + char *pnt = irt->rt.val; + unsigned int key = 0; + int c=0; + + key += pnt[c]; + key += pnt[c + 1]; + key += pnt[c + 2]; + key += pnt[c + 3]; + key += pnt[c + 4]; + key += pnt[c + 5]; + key += pnt[c + 6]; + key += pnt[c + 7]; + + return (key); +} + +/* + * Comparison function for import rt hash + */ +static int +import_rt_hash_cmp (const void *p1, const void *p2) +{ + const struct irt_node *irt1 = p1; + const struct irt_node *irt2 = p2; + + if (irt1 == NULL && irt2 == NULL) + return 1; + + if (irt1 == NULL || irt2 == NULL) + return 0; + + return(memcmp(irt1->rt.val, irt2->rt.val, ECOMMUNITY_SIZE) == 0); +} + +/* + * Free a VNI entry; iterator function called during cleanup. + */ +static void +free_vni_entry (struct hash_backet *backet, struct bgp *bgp) +{ +} + + +/* + * Public functions. + */ int bgp_nlri_parse_evpn(struct peer *peer, struct attr *attr, @@ -225,3 +314,41 @@ bgp_packet_mpattr_route_type_5(struct stream *s, stream_put3(s, 0); return; } + +/* + * Cleanup EVPN information - invoked at the time of bgpd exit or when the + * BGP instance (default) is being freed. + */ +void +bgp_evpn_cleanup (struct bgp *bgp) +{ + hash_iterate (bgp->vnihash, + (void (*) (struct hash_backet *, void *)) + free_vni_entry, bgp); + hash_free (bgp->import_rt_hash); + bgp->import_rt_hash = NULL; + hash_free (bgp->vnihash); + bgp->vnihash = NULL; + bf_free (bgp->rd_idspace); +} + +/* + * Initialization for EVPN + * Create + * VNI hash table + * hash for RT to VNI + * unique rd id space for auto derivation of RD for VNIs + */ +void +bgp_evpn_init (struct bgp *bgp) +{ + bgp->vnihash = hash_create (vni_hash_key_make, + vni_hash_cmp, + "BGP VNI Hash"); + bgp->import_rt_hash = hash_create (import_rt_hash_key_make, + import_rt_hash_cmp, + "BGP Import RT Hash"); + bf_init (bgp->rd_idspace, UINT16_MAX); + /*assign 0th index in the bitfield, so that we start with id 1*/ + bf_assign_zero_index (bgp->rd_idspace); +} diff --git a/bgpd/bgp_evpn.h b/bgpd/bgp_evpn.h index feabc9cd27..8a4e27c0cb 100644 --- a/bgpd/bgp_evpn.h +++ b/bgpd/bgp_evpn.h @@ -28,6 +28,12 @@ extern void bgp_packet_mpattr_route_type_5(struct stream *s, struct prefix *p, struct prefix_rd *prd, mpls_label_t *label, struct attr *attr); + +extern void +bgp_evpn_cleanup (struct bgp *bgp); +extern void +bgp_evpn_init (struct bgp *bgp); + /* EVPN route types as per RFC7432 and * as per draft-ietf-bess-evpn-prefix-advertisement-02 */ diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index d7ddd5db8a..87912693f2 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -241,6 +241,7 @@ bgp_router_id_set (struct bgp *bgp, const struct in_addr *id) BGP_NOTIFY_CEASE_CONFIG_CHANGE); } } + return 0; } @@ -3004,6 +3005,7 @@ bgp_create (as_t *as, const char *name, enum bgp_instance_type inst_type) QOBJ_REG (bgp, bgp); update_bgp_group_init(bgp); + bgp_evpn_init(bgp); return bgp; } @@ -3355,6 +3357,8 @@ bgp_free (struct bgp *bgp) bgp_scan_finish (bgp); bgp_address_destroy (bgp); + bgp_evpn_cleanup (bgp); + if (bgp->name) XFREE(MTYPE_BGP, bgp->name); diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h index 5dc25d00a9..31aa6163b0 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -33,6 +33,7 @@ #include "linklist.h" #include "defaults.h" #include "bgp_memory.h" +#include "bitfield.h" #define BGP_MAX_HOSTNAME 64 /* Linux max, is larger than most other sys */ @@ -367,6 +368,20 @@ struct bgp struct rfapi *rfapi; #endif + /* EVPN related information */ + + /* EVI hash table */ + struct hash *vnihash; + + /* EVPN enable - advertise local VNIs and their MACs etc. */ + int advertise_all_vni; + + /* Hash table of Import RTs to EVIs */ + struct hash *import_rt_hash; + + /* Id space for automatic RD derivation for an EVI */ + bitfield_t rd_idspace; + QOBJ_FIELDS }; DECLARE_QOBJ_TYPE(bgp) -- 2.39.5