]> git.puffer.fish Git - matthieu/frr.git/commitdiff
bgpd: route type 5 internal structures plus processing
authorPhilippe Guibert <philippe.guibert@6wind.com>
Mon, 5 Sep 2016 12:07:01 +0000 (14:07 +0200)
committerPhilippe Guibert <philippe.guibert@6wind.com>
Tue, 14 Feb 2017 12:58:58 +0000 (13:58 +0100)
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, including ESI,
gatewayIP and label information.

Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
bgpd/bgp_attr.c
bgpd/bgp_attr.h
bgpd/bgp_route.c
bgpd/bgp_route.h

index 7dc42e719f8f42735b92033a329cf14add6aad36..a0e8d5499bc47bfa1d530415c8416a3bb653590c 100644 (file)
@@ -419,6 +419,18 @@ encap_finish (void)
 #endif
 }
 
+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;
 
@@ -730,7 +742,8 @@ attrhash_cmp (const void *p1, const void *p2)
 #if ENABLE_BGP_VNC
          && encap_same(ae1->vnc_subtlvs, ae2->vnc_subtlvs)
 #endif
-          && IPV4_ADDR_SAME (&ae1->originator_id, &ae2->originator_id))
+          && IPV4_ADDR_SAME (&ae1->originator_id, &ae2->originator_id)
+          && overlay_index_same(ae1, ae2))
         return 1;
       else if (ae1 || ae2)
         return 0;
index c5799ccd0dd54a19a1b84587a7caf4b466af0aef..3ccf65029cebe45014163c7536f87713ba42c423 100644 (file)
@@ -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
 
@@ -80,6 +82,13 @@ struct bgp_tea_options {
 
 #endif
 
+/* 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.
@@ -131,6 +140,8 @@ struct attr_extra
 #if ENABLE_BGP_VNC
   struct bgp_attr_encap_subtlv *vnc_subtlvs;           /* VNC-specific */
 #endif
+  /* EVPN */
+  struct overlay_index evpn_overlay;
 };
 
 /* BGP core attribute structure. */
index df2c3d8e73db92e70cd0a214a928958e60317c1a..f80c24dcba622b53f729ae5a3f332532b657f9c2 100644 (file)
@@ -68,6 +68,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 #include "bgpd/rfapi/vnc_import_bgp.h"
 #include "bgpd/rfapi/vnc_export_bgp.h"
 #endif
+#include "bgpd/bgp_evpn.h"
 
 /* Extern from bgp_dump.c */
 extern const char *bgp_origin_str[];
@@ -2270,6 +2271,68 @@ info_make (int type, int sub_type, u_short instance, struct peer *peer, struct a
   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
+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_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));
+}
+
 /* Check if received nexthop is valid or not. */
 static int
 bgp_update_martian_nexthop (struct bgp *bgp, afi_t afi, safi_t safi, struct attr *attr)
@@ -2448,7 +2511,9 @@ bgp_update (struct peer *peer, struct prefix *p, u_int32_t addpath_id,
 
       /* Same attribute comes in. */
       if (!CHECK_FLAG (ri->flags, BGP_INFO_REMOVED) 
-          && attrhash_cmp (ri->attr, attr_new))
+          && attrhash_cmp (ri->attr, attr_new)
+          && (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
@@ -2568,7 +2633,7 @@ bgp_update (struct peer *peer, struct prefix *p, u_int32_t addpath_id,
       ri->attr = attr_new;
 
       /* Update MPLS tag.  */
-      if (safi == SAFI_MPLS_VPN)
+      if (safi == SAFI_MPLS_VPN || safi == SAFI_EVPN)
         memcpy ((bgp_info_extra_get (ri))->tag, tag, 3);
 
 #if ENABLE_BGP_VNC
@@ -2589,6 +2654,12 @@ bgp_update (struct peer *peer, struct prefix *p, u_int32_t addpath_id,
             }
         }
 #endif
+      /* Update Overlay Index */
+      if(afi == AFI_L2VPN)
+        {
+          overlay_index_update(ri->attr, evpn==NULL?NULL:&evpn->eth_s_id,
+                               evpn==NULL?NULL:&evpn->gw_ip);
+        }
 
       /* Update bgp route dampening information.  */
       if (CHECK_FLAG (bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
@@ -2693,9 +2764,15 @@ bgp_update (struct peer *peer, struct prefix *p, u_int32_t addpath_id,
   new = info_make(type, sub_type, 0, peer, attr_new, rn);
 
   /* Update MPLS tag. */
-  if (safi == SAFI_MPLS_VPN)
+  if (safi == SAFI_MPLS_VPN || safi == SAFI_EVPN)
     memcpy ((bgp_info_extra_get (new))->tag, tag, 3);
 
+  /* Update Overlay Index */
+  if(afi == AFI_L2VPN)
+    {
+      overlay_index_update(new->attr, evpn==NULL?NULL:&evpn->eth_s_id,
+                           evpn==NULL?NULL:&evpn->gw_ip);
+    }
   /* Nexthop reachability check. */
   if ((afi == AFI_IP || afi == AFI_IP6) && safi == SAFI_UNICAST)
     {
@@ -3616,6 +3693,8 @@ bgp_static_free (struct bgp_static *bgp_static)
 {
   if (bgp_static->rmap.name)
     XFREE(MTYPE_ROUTE_MAP_NAME, bgp_static->rmap.name);
+  if(bgp_static->eth_s_id)
+    XFREE(MTYPE_ATTR, bgp_static->eth_s_id);
   XFREE (MTYPE_BGP_STATIC, bgp_static);
 }
 
@@ -3922,6 +4001,8 @@ bgp_static_update_safi (struct bgp *bgp, struct prefix *p,
   attr.med = bgp_static->igpmetric;
   attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC);
 
+  if(afi == AFI_L2VPN)
+      overlay_index_update(&attr, bgp_static->eth_s_id, NULL);
   /* Apply route-map. */
   if (bgp_static->rmap.name)
     {
@@ -3965,7 +4046,10 @@ bgp_static_update_safi (struct bgp *bgp, struct prefix *p,
 
   if (ri)
     {
+      union gw_addr add;
+      memset(&add, 0, sizeof(union gw_addr));
       if (attrhash_cmp (ri->attr, attr_new) &&
+          overlay_index_equal(afi, ri, bgp_static->eth_s_id, &add) &&
           !CHECK_FLAG(ri->flags, BGP_INFO_REMOVED))
         {
           bgp_unlock_node (rn);
index 4a24b0f376c437e02183c2925bbc574466cf5794..243c5afb007702725ef64daca154461d13099e31 100644 (file)
@@ -203,6 +203,10 @@ struct bgp_static
 
   /* MPLS label.  */
   u_char tag[3];
+
+  /* EVPN */
+  struct eth_segment_id *eth_s_id;
+  char *router_mac;
 };
 
 #define BGP_NEXTHOP_AFI_FROM_NHLEN(nhlen) \