Mailing List Archive

[PATCH 27/57] bgpd: route type 5 internal structures plus processing
The commit introduces the changes to be done to carry route type 5 EVPN
information in bgp extra attribute information. The commit also handles
the update processing for route type 5 information.

Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
---
bgpd/bgp_attr.c | 16 ++++-
bgpd/bgp_attr.h | 14 +++++
bgpd/bgp_route.c | 173 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
bgpd/bgp_route.h | 5 ++
4 files changed, 205 insertions(+), 3 deletions(-)

diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c
index 8741c4af3441..c7564ae49fb8 100644
--- a/bgpd/bgp_attr.c
+++ b/bgpd/bgp_attr.c
@@ -311,6 +311,18 @@ encap_same(struct bgp_attr_encap_subtlv *h1, struct bgp_attr_encap_subtlv *h2)
return 1;
}

+static bool
+overlay_index_same(const struct attr_extra *ae1, const struct attr_extra *ae2)
+{
+ if(!ae1 && ae2)
+ return false;
+ if(!ae2 && ae1)
+ return false;
+ if(!ae1 && !ae2)
+ return false;
+ return !memcmp(&(ae1->evpn_overlay), &(ae2->evpn_overlay), sizeof(struct overlay_index));
+}
+
/* Unknown transit attribute. */
static struct hash *transit_hash;

@@ -551,7 +563,9 @@ attrhash_cmp (const void *p1, const void *p2)
&& ae1->transit == ae2->transit
&& (ae1->encap_tunneltype == ae2->encap_tunneltype)
&& encap_same(ae1->encap_subtlvs, ae2->encap_subtlvs)
- && IPV4_ADDR_SAME (&ae1->originator_id, &ae2->originator_id))
+ && IPV4_ADDR_SAME (&ae1->originator_id, &ae2->originator_id)
+ && ae1->eth_t_id == ae2->eth_t_id
+ && overlay_index_same(ae1, ae2))
return 1;
else if (ae1 || ae2)
return 0;
diff --git a/bgpd/bgp_attr.h b/bgpd/bgp_attr.h
index 3bd7aface174..64a7464177df 100644
--- a/bgpd/bgp_attr.h
+++ b/bgpd/bgp_attr.h
@@ -21,6 +21,8 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#ifndef _QUAGGA_BGP_ATTR_H
#define _QUAGGA_BGP_ATTR_H

+#include "bgp_attr_evpn.h"
+
/* Simple bit mapping. */
#define BITMAP_NBBY 8

@@ -54,6 +56,13 @@ struct bgp_attr_encap_subtlv {
uint8_t value[1]; /* will be extended */
};

+/* Overlay Index Info */
+struct overlay_index
+{
+ struct eth_segment_id eth_s_id;
+ union gw_addr gw_ip;
+};
+
/* Additional/uncommon BGP attributes.
* lazily allocated as and when a struct attr
* requires it.
@@ -95,6 +104,11 @@ struct attr_extra

/* route tag */
route_tag_t tag;
+
+ /* EVPN */
+ uint32_t eth_t_id;
+ struct overlay_index evpn_overlay;
+ short use_gw;
};

/* BGP core attribute structure. */
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index 32577c299f6a..3c8ebcab8676 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -57,6 +57,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#include "bgpd/bgp_vty.h"
#include "bgpd/bgp_mpath.h"
#include "bgpd/bgp_nht.h"
+#include "bgpd/bgp_evpn.h"

/* Extern from bgp_dump.c */
extern const char *bgp_origin_str[];
@@ -2526,6 +2527,86 @@ info_make (int type, int sub_type, struct peer *peer, struct attr *attr,
return new;
}

+static void
+overlay_index_update(struct attr *attr, struct eth_segment_id *eth_s_id, union gw_addr *gw_ip)
+{
+ struct attr_extra *extra;
+
+ if(!attr)
+ return;
+ extra = bgp_attr_extra_get(attr);
+
+ if(eth_s_id == NULL)
+ {
+ memset(&(extra->evpn_overlay.eth_s_id),0, sizeof(struct eth_segment_id));
+ }
+ else
+ {
+ memcpy(&(extra->evpn_overlay.eth_s_id), eth_s_id, sizeof(struct eth_segment_id));
+ }
+ if(gw_ip == NULL)
+ {
+ memset(&(extra->evpn_overlay.gw_ip), 0, sizeof(union gw_addr));
+ }
+ else
+ {
+ memcpy(&(extra->evpn_overlay.gw_ip),gw_ip, sizeof(union gw_addr));
+ }
+}
+
+static bool
+eth_tag_id_equal(afi_t afi, struct bgp_info *info, uint32_t *eth_t_id)
+{
+ uint32_t local_eth_t_id;
+
+ if(afi != AFI_INTERNAL_L2VPN)
+ return true;
+ if (!info->attr || !info->attr->extra) {
+ local_eth_t_id = 0;
+ if(eth_t_id == NULL)
+ return true;
+ } else {
+ local_eth_t_id = info->attr->extra->eth_t_id;
+ }
+ if(eth_t_id && (local_eth_t_id == *eth_t_id))
+ return true;
+ if (local_eth_t_id == 0)
+ return true;
+ return false;
+}
+
+static bool
+overlay_index_equal(afi_t afi, struct bgp_info *info, struct eth_segment_id *eth_s_id, union gw_addr *gw_ip)
+{
+ struct eth_segment_id *info_eth_s_id, *info_eth_s_id_remote;
+ union gw_addr *info_gw_ip, *info_gw_ip_remote;
+ char temp[16];
+
+ if(afi != AFI_INTERNAL_L2VPN)
+ return true;
+ if (!info->attr || !info->attr->extra) {
+ memset(&temp, 0, 16);
+ info_eth_s_id = (struct eth_segment_id *)&temp;
+ info_gw_ip = (union gw_addr *)&temp;
+ if(eth_s_id == NULL && gw_ip == NULL)
+ return true;
+ } else {
+ info_eth_s_id = &(info->attr->extra->evpn_overlay.eth_s_id);
+ info_gw_ip = &(info->attr->extra->evpn_overlay.gw_ip);
+ }
+ if(gw_ip == NULL)
+ info_gw_ip_remote = (union gw_addr *)&temp;
+ else
+ info_gw_ip_remote = gw_ip;
+ if(eth_s_id == NULL)
+ info_eth_s_id_remote = (struct eth_segment_id *)&temp;
+ else
+ info_eth_s_id_remote = eth_s_id;
+ if(!memcmp(info_gw_ip, info_gw_ip_remote, sizeof(union gw_addr)))
+ return false;
+ return !memcmp(info_eth_s_id, info_eth_s_id_remote, sizeof(struct eth_segment_id));
+}
+
static bool
labels_equal(struct bgp_info *info, uint32_t *labels, size_t nlabels)
{
@@ -2640,7 +2721,11 @@ bgp_update_rsclient (struct peer *rsclient, afi_t afi, safi_t safi,
/* Same attribute comes in. */
if (!CHECK_FLAG(ri->flags, BGP_INFO_REMOVED)
&& attrhash_cmp (ri->attr, attr_new)
- && labels_equal (ri, labels, nlabels))
+ && labels_equal (ri, labels, nlabels)
+ && eth_tag_id_equal(afi, ri, evpn==NULL?NULL:&evpn->eth_t_id)
+ && (overlay_index_equal(afi, ri,
+ evpn==NULL?NULL:&evpn->eth_s_id,
+ evpn==NULL?NULL:&evpn->gw_ip)))
{


@@ -2684,6 +2769,19 @@ bgp_update_rsclient (struct peer *rsclient, afi_t afi, safi_t safi,
else if (ri->extra)
ri->extra->nlabels = 0;

+ /* Update Overlay Index */
+ if(afi == AFI_INTERNAL_L2VPN)
+ {
+ overlay_index_update(ri->attr, evpn==NULL?NULL:&evpn->eth_s_id,
+ evpn==NULL?NULL:&evpn->gw_ip);
+ if(ri->attr && ri->attr->extra)
+ {
+ if(evpn && evpn->eth_t_id)
+ ri->attr->extra->eth_t_id = evpn->eth_t_id;
+ else
+ ri->attr->extra->eth_t_id = 0;
+ }
+ }
bgp_info_set_flag (rn, ri, BGP_INFO_VALID);

/* Process change. */
@@ -2713,6 +2811,19 @@ bgp_update_rsclient (struct peer *rsclient, afi_t afi, safi_t safi,
memcpy (ri->extra->labels, labels, sizeof(*labels) * nlabels);
}

+ /* Update Overlay Index */
+ if(afi == AFI_INTERNAL_L2VPN)
+ {
+ overlay_index_update(new->attr, evpn==NULL?NULL:&evpn->eth_s_id,
+ evpn==NULL?NULL:&evpn->gw_ip);
+ if(new->attr && new->attr->extra)
+ {
+ if(evpn && evpn->eth_t_id)
+ new->attr->extra->eth_t_id = evpn->eth_t_id;
+ else
+ new->attr->extra->eth_t_id = 0;
+ }
+ }
bgp_info_set_flag (rn, new, BGP_INFO_VALID);

/* Register new BGP information. */
@@ -2897,7 +3008,10 @@ bgp_update_main (struct peer *peer, struct prefix *p, struct attr *attr,
/* Same attribute comes in. */
if (!CHECK_FLAG (ri->flags, BGP_INFO_REMOVED)
&& attrhash_cmp (ri->attr, attr_new)
- && labels_equal (ri, labels, nlabels))
+ && labels_equal (ri, labels, nlabels)
+ && eth_tag_id_equal(afi, ri, evpn==NULL?0:&evpn->eth_t_id)
+ && (overlay_index_equal(afi, ri, evpn==NULL?NULL:&evpn->eth_s_id,
+ evpn==NULL?NULL:&evpn->gw_ip)))
{
if (CHECK_FLAG (bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
&& peer->sort == BGP_PEER_EBGP
@@ -2992,6 +3106,19 @@ bgp_update_main (struct peer *peer, struct prefix *p, struct attr *attr,
else if (ri->extra)
ri->extra->nlabels = 0;

+ /* Update Overlay Index */
+ if(afi == AFI_INTERNAL_L2VPN)
+ {
+ overlay_index_update(ri->attr, evpn==NULL?NULL:&evpn->eth_s_id,
+ evpn==NULL?NULL:&evpn->gw_ip);
+ if(ri->attr && ri->attr->extra)
+ {
+ if(evpn && evpn->eth_t_id)
+ ri->attr->extra->eth_t_id = evpn->eth_t_id;
+ else
+ ri->attr->extra->eth_t_id = 0;
+ }
+ }
bgp_attr_flush (&new_attr);

/* Update bgp route dampening information. */
@@ -3065,6 +3192,19 @@ bgp_update_main (struct peer *peer, struct prefix *p, struct attr *attr,
memcpy (new->extra->labels, labels, sizeof(*labels) * nlabels);
}

+ /* Update Overlay Index */
+ if(afi == AFI_INTERNAL_L2VPN)
+ {
+ overlay_index_update(new->attr, evpn==NULL?NULL:&evpn->eth_s_id,
+ evpn==NULL?NULL:&evpn->gw_ip);
+ if(new->attr && new->attr->extra)
+ {
+ if(evpn && evpn->eth_t_id)
+ new->attr->extra->eth_t_id = evpn->eth_t_id;
+ else
+ new->attr->extra->eth_t_id = 0;
+ }
+ }
/* Nexthop reachability check. */
if ((afi == AFI_IP || afi == AFI_IP6) && safi == SAFI_UNICAST)
{
@@ -4085,6 +4225,8 @@ bgp_static_free (struct bgp_static *bgp_static)
{
if (bgp_static->rmap.name)
free (bgp_static->rmap.name);
+ if(bgp_static->eth_s_id)
+ XFREE(MTYPE_ATTR, bgp_static->eth_s_id);
XFREE (MTYPE_BGP_STATIC, bgp_static);
}

@@ -4581,6 +4723,28 @@ bgp_static_update_safi (struct bgp *bgp, struct prefix *p,
bgp_attr_extra_get (&attr)->ecommunity = ecommunity_dup (bgp_static->ecomm);
attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES);
}
+ if(afi == AFI_INTERNAL_L2VPN)
+ {
+ if (bgp_static->igpnexthop.s_addr)
+ {
+ union gw_addr add;
+
+ memset(&add, 0, sizeof(union gw_addr));
+ add.ipv4.s_addr = bgp_static->igpnexthop.s_addr;
+ overlay_index_update(&attr, bgp_static->eth_s_id, &add);
+ }
+ else
+ {
+ overlay_index_update(&attr, bgp_static->eth_s_id, NULL);
+ }
+ if((&attr)->extra)
+ (&attr)->extra->eth_t_id = bgp_static->eth_t_id;
+ }
+ if (bgp_static->igpnexthop.s_addr)
+ {
+ bgp_attr_extra_get (&attr)->mp_nexthop_global_in = bgp_static->igpnexthop;
+ bgp_attr_extra_get (&attr)->mp_nexthop_len = IPV4_MAX_BYTELEN;
+ }
/* Apply route-map. */
if (bgp_static->rmap.name)
{
@@ -4624,7 +4788,12 @@ bgp_static_update_safi (struct bgp *bgp, struct prefix *p,

if (ri)
{
+ union gw_addr add;
+ memset(&add, 0, sizeof(union gw_addr));
+ add.ipv4.s_addr = bgp_static->igpnexthop.s_addr;
if (attrhash_cmp (ri->attr, attr_new) &&
+ eth_tag_id_equal(afi, ri, &bgp_static->eth_t_id) &&
+ overlay_index_equal(afi, ri, bgp_static->eth_s_id, &add) &&
!CHECK_FLAG(ri->flags, BGP_INFO_REMOVED))
{
bgp_unlock_node (rn);
diff --git a/bgpd/bgp_route.h b/bgpd/bgp_route.h
index 5047b5c48b18..4301088fed3d 100644
--- a/bgpd/bgp_route.h
+++ b/bgpd/bgp_route.h
@@ -149,6 +149,11 @@ struct bgp_static
/* MPLS label. */
uint32_t labels[BGP_MAX_LABELS];
size_t nlabels;
+
+ /* EVPN */
+ uint32_t eth_t_id;
+ struct eth_segment_id *eth_s_id;
+ char *router_mac;
};

#define BGP_INFO_COUNTABLE(BI) \
--
2.1.4


_______________________________________________
Quagga-dev mailing list
Quagga-dev@lists.quagga.net
https://lists.quagga.net/mailman/listinfo/quagga-dev