]> git.puffer.fish Git - matthieu/frr.git/commitdiff
bgpd rfapi: fix issue where advertised prefixes were not being disambiguated
authorLou Berger <lberger@labn.net>
Sun, 15 Jan 2017 21:43:20 +0000 (16:43 -0500)
committerLou Berger <lberger@labn.net>
Tue, 17 Jan 2017 19:59:10 +0000 (14:59 -0500)
        by RD

Signed-off-by: Lou Berger <lberger@labn.net>
bgpd/rfapi/rfapi.c
bgpd/rfapi/rfapi_ap.c
bgpd/rfapi/rfapi_ap.h
bgpd/rfapi/rfapi_private.h
bgpd/rfapi/rfapi_rib.c
bgpd/rfapi/rfapi_rib.h
bgpd/rfapi/rfapi_vty.c

index bc2fb9526fb3b1f0075cf6ec8ab4194267dcaeb9..599d6e88bf63289dd68127298f87ca3907b10e27 100644 (file)
@@ -2777,7 +2777,7 @@ rfapi_register (
        NULL,
        action == RFAPI_REGISTER_KILL);
 
-      if (0 == rfapiApDelete (bgp, rfd, &p, pfx_mac, &adv_tunnel))
+      if (0 == rfapiApDelete (bgp, rfd, &p, pfx_mac, &prd, &adv_tunnel))
         {
           if (adv_tunnel)
             rfapiTunnelRouteAnnounce (bgp, rfd, &rfd->max_prefix_lifetime);
index 4b8eb9511b363df43a13815e1f22c8a2bdebdbd0..4c415504fa3f6a04a51e89ec962f80d9ee9b6fa2 100644 (file)
@@ -103,12 +103,11 @@ sl_adb_lifetime_cmp (void *adb1, void *adb2)
   return 0;
 }
 
-
 void
 rfapiApInit (struct rfapi_advertised_prefixes *ap)
 {
-  ap->ipN_by_prefix = skiplist_new (0, vnc_prefix_cmp, NULL);
-  ap->ip0_by_ether = skiplist_new (0, vnc_prefix_cmp, NULL);
+  ap->ipN_by_prefix = skiplist_new (0, rfapi_rib_key_cmp, NULL);
+  ap->ip0_by_ether = skiplist_new (0, rfapi_rib_key_cmp, NULL);
   ap->by_lifetime = skiplist_new (0, sl_adb_lifetime_cmp, NULL);
 }
 
@@ -192,7 +191,7 @@ rfapiApReadvertiseAll (struct bgp *bgp, struct rfapi_descriptor *rfd)
        * TBD this is not quite right. When pfx_ip is 0/32 or 0/128,
        * we need to substitute the VN address as the prefix
        */
-      add_vnc_route (rfd, bgp, SAFI_MPLS_VPN, &adb->prefix_ip, &prd,    /* RD to use (0 for ENCAP) */
+      add_vnc_route (rfd, bgp, SAFI_MPLS_VPN, &adb->u.s.prefix_ip, &prd,    /* RD to use (0 for ENCAP) */
                      &rfd->vn_addr,     /* nexthop */
                      &local_pref, &adb->lifetime, NULL, NULL,   /* struct rfapi_un_option */
                      NULL,      /* struct rfapi_vn_option */
@@ -221,11 +220,11 @@ rfapiApWithdrawAll (struct bgp *bgp, struct rfapi_descriptor *rfd)
       struct prefix pfx_vn_buf;
       struct prefix *pfx_ip;
 
-      if (!(RFAPI_0_PREFIX (&adb->prefix_ip) &&
-            RFAPI_HOST_PREFIX (&adb->prefix_ip)))
+      if (!(RFAPI_0_PREFIX (&adb->u.s.prefix_ip) &&
+            RFAPI_HOST_PREFIX (&adb->u.s.prefix_ip)))
         {
 
-          pfx_ip = &adb->prefix_ip;
+          pfx_ip = &adb->u.s.prefix_ip;
 
         }
       else
@@ -247,7 +246,7 @@ rfapiApWithdrawAll (struct bgp *bgp, struct rfapi_descriptor *rfd)
             }
         }
 
-      del_vnc_route (rfd, rfd->peer, bgp, SAFI_MPLS_VPN, pfx_ip ? pfx_ip : &pfx_vn_buf, &adb->prd,      /* RD to use (0 for ENCAP) */
+      del_vnc_route (rfd, rfd->peer, bgp, SAFI_MPLS_VPN, pfx_ip ? pfx_ip : &pfx_vn_buf, &adb->u.s.prd,      /* RD to use (0 for ENCAP) */
                      ZEBRA_ROUTE_BGP, BGP_ROUTE_RFP, NULL, 0);
     }
 }
@@ -404,19 +403,19 @@ rfapiApAdjustLifetimeStats (
         {
 
           void *cursor;
-          struct prefix *prefix;
-          struct rfapi_adb *adb;
+          struct rfapi_rib_key rk;
+          struct rfapi_adb    *adb;
           int rc;
 
           vnc_zlog_debug_verbose ("%s: walking to find new min/max", __func__);
 
           cursor = NULL;
           for (rc = skiplist_next (rfd->advertised.ipN_by_prefix,
-                                   (void **) &prefix, (void **) &adb,
+                                   (void **) &rk, (void **) &adb,
                                    &cursor); !rc;
                rc =
                skiplist_next (rfd->advertised.ipN_by_prefix,
-                              (void **) &prefix, (void **) &adb, &cursor))
+                              (void **) &rk, (void **) &adb, &cursor))
             {
 
               uint32_t lt = adb->lifetime;
@@ -428,10 +427,10 @@ rfapiApAdjustLifetimeStats (
             }
           cursor = NULL;
           for (rc = skiplist_next (rfd->advertised.ip0_by_ether,
-                                   (void **) &prefix, (void **) &adb,
+                                   (void **) &rk, (void **) &adb,
                                    &cursor); !rc;
                rc =
-               skiplist_next (rfd->advertised.ip0_by_ether, (void **) &prefix,
+               skiplist_next (rfd->advertised.ip0_by_ether, (void **) &rk,
                               (void **) &adb, &cursor))
             {
 
@@ -483,14 +482,15 @@ rfapiApAdd (
   struct rfapi_adb *adb;
   uint32_t old_lifetime = 0;
   int use_ip0 = 0;
+  struct rfapi_rib_key rk;
 
+  rfapi_rib_key_init(pfx_ip, prd, pfx_eth, &rk);
   if (RFAPI_0_PREFIX (pfx_ip) && RFAPI_HOST_PREFIX (pfx_ip))
     {
       use_ip0 = 1;
       assert (pfx_eth);
-
       rc =
-        skiplist_search (rfd->advertised.ip0_by_ether, pfx_eth,
+        skiplist_search (rfd->advertised.ip0_by_ether, &rk,
                          (void **) &adb);
 
     }
@@ -499,7 +499,7 @@ rfapiApAdd (
 
       /* find prefix in advertised prefixes list */
       rc =
-        skiplist_search (rfd->advertised.ipN_by_prefix, pfx_ip,
+        skiplist_search (rfd->advertised.ipN_by_prefix, &rk,
                          (void **) &adb);
     }
 
@@ -510,19 +510,17 @@ rfapiApAdd (
       adb = XCALLOC (MTYPE_RFAPI_ADB, sizeof (struct rfapi_adb));
       assert (adb);
       adb->lifetime = lifetime;
-      adb->prefix_ip = *pfx_ip;
-      if (pfx_eth)
-        adb->prefix_eth = *pfx_eth;
+      adb->u.key = rk;
 
       if (use_ip0)
         {
           assert (pfx_eth);
-          skiplist_insert (rfd->advertised.ip0_by_ether, &adb->prefix_eth,
+          skiplist_insert (rfd->advertised.ip0_by_ether, &adb->u.key,
                            adb);
         }
       else
         {
-          skiplist_insert (rfd->advertised.ipN_by_prefix, &adb->prefix_ip,
+          skiplist_insert (rfd->advertised.ipN_by_prefix, &adb->u.key,
                            adb);
         }
 
@@ -537,19 +535,12 @@ rfapiApAdd (
           adb->lifetime = lifetime;
           assert (!skiplist_insert (rfd->advertised.by_lifetime, adb, adb));
         }
-
-      if (!use_ip0 && pfx_eth && prefix_cmp (&adb->prefix_eth, pfx_eth))
-        {
-          /* mac address changed */
-          adb->prefix_eth = *pfx_eth;
-        }
     }
   adb->cost = cost;
   if (l2o)
     adb->l2o = *l2o;
   else
     memset (&adb->l2o, 0, sizeof (struct rfapi_l2address_option));
-  adb->prd = *prd;
 
   if (rfapiApAdjustLifetimeStats
       (rfd, (rc ? NULL : &old_lifetime), &lifetime))
@@ -568,16 +559,19 @@ rfapiApDelete (
   struct rfapi_descriptor      *rfd,
   struct prefix                        *pfx_ip,
   struct prefix                        *pfx_eth,
+  struct prefix_rd             *prd,
   int                          *advertise_tunnel)      /* out */
 {
   int rc;
   struct rfapi_adb *adb;
   uint32_t old_lifetime;
   int use_ip0 = 0;
+  struct rfapi_rib_key rk;
 
   if (advertise_tunnel)
     *advertise_tunnel = 0;
 
+  rfapi_rib_key_init(pfx_ip, prd, pfx_eth, &rk);
   /* find prefix in advertised prefixes list */
   if (RFAPI_0_PREFIX (pfx_ip) && RFAPI_HOST_PREFIX (pfx_ip))
     {
@@ -585,7 +579,7 @@ rfapiApDelete (
       assert (pfx_eth);
 
       rc =
-        skiplist_search (rfd->advertised.ip0_by_ether, pfx_eth,
+        skiplist_search (rfd->advertised.ip0_by_ether, &rk,
                          (void **) &adb);
 
     }
@@ -594,7 +588,7 @@ rfapiApDelete (
 
       /* find prefix in advertised prefixes list */
       rc =
-        skiplist_search (rfd->advertised.ipN_by_prefix, pfx_ip,
+        skiplist_search (rfd->advertised.ipN_by_prefix, &rk,
                          (void **) &adb);
     }
 
@@ -607,11 +601,11 @@ rfapiApDelete (
 
   if (use_ip0)
     {
-      rc = skiplist_delete (rfd->advertised.ip0_by_ether, pfx_eth, NULL);
+      rc = skiplist_delete (rfd->advertised.ip0_by_ether, &rk, NULL);
     }
   else
     {
-      rc = skiplist_delete (rfd->advertised.ipN_by_prefix, pfx_ip, NULL);
+      rc = skiplist_delete (rfd->advertised.ipN_by_prefix, &rk, NULL);
     }
   assert (!rc);
 
index f2805f49cba544e48467dcdafe607c2d2605ce81..8a59f05274af08f722fd8dd5737a1b09d66086ea 100644 (file)
@@ -93,6 +93,7 @@ rfapiApDelete (
   struct rfapi_descriptor      *rfd,
   struct prefix                        *pfx_ip,
   struct prefix                        *pfx_eth,
+  struct prefix_rd             *prd,
   int                          *advertise_tunnel); /* out */
 
 
index 33390c4f55f20a5091af6be86d50814f33148247..00f90e35fc827197dc07901516a68603e447bf21 100644 (file)
 
 #include "rfapi.h"
 
-/*
- * RFAPI Advertisement Data Block
- *
- * Holds NVE prefix advertisement information
- */
-struct rfapi_adb
-{
-  struct prefix                        prefix_ip;
-  struct prefix                        prefix_eth;     /* now redundant with l2o */
-  struct prefix_rd             prd;
-  uint32_t                     lifetime;
-  uint8_t                      cost;
-  struct rfapi_l2address_option        l2o;
-};
-
 /*
  * Lists of rfapi_adb. Each rfapi_adb is referenced twice:
  *
@@ -62,7 +47,6 @@ struct rfapi_advertised_prefixes
   struct skiplist *by_lifetime;   /* all */
 };
 
-
 struct rfapi_descriptor
 {
   struct route_node            *un_node;       /* backref to un table */
@@ -378,9 +362,6 @@ rfp_cost_to_localpref (uint8_t cost);
 extern int
 rfapi_set_autord_from_vn (struct prefix_rd *rd, struct rfapi_ip_addr *vn);
 
-extern void
-rfapiAdbFree (struct rfapi_adb *adb);
-
 extern struct rfapi_nexthop *
 rfapi_nexthop_new (struct rfapi_nexthop *copyme);
 
index 6aae35e6354d08362f5fc858c6007601964e13d5..3a4a1592155a89c6360689609644fa4a7c998d7c 100644 (file)
@@ -405,10 +405,26 @@ rfapiRibStartTimer (
   assert (ri->timer);
 }
 
+extern void
+rfapi_rib_key_init (struct prefix        *prefix, /* may be NULL */
+                    struct prefix_rd     *rd,     /* may be NULL */
+                    struct prefix        *aux,    /* may be NULL */
+                    struct rfapi_rib_key *rk)
+  
+{
+  memset((void *)rk, 0, sizeof(struct rfapi_rib_key));
+  if (prefix)
+    rk->vn = *prefix;
+  if (rd)
+    rk->rd = *rd;
+  if (aux)
+    rk->aux_prefix = *aux;
+}
+
 /*
  * Compares two <struct rfapi_rib_key>s
  */
-static int
+int
 rfapi_rib_key_cmp (void *k1, void *k2)
 {
   struct rfapi_rib_key *a = (struct rfapi_rib_key *) k1;
index 2a111946f7d817f8a2b3ce9bd81bdc5efb1ef6fc..74331a28d021f6865406fb63fb4a12fe055d5e6c 100644 (file)
@@ -45,6 +45,27 @@ struct rfapi_rib_key
    */
   struct prefix aux_prefix;
 };
+#include "rfapi.h"
+
+/*
+ * RFAPI Advertisement Data Block
+ *
+ * Holds NVE prefix advertisement information
+ */
+struct rfapi_adb
+{
+  union {
+    struct {
+      struct prefix            prefix_ip;
+      struct prefix_rd         prd;
+      struct prefix            prefix_eth;
+    } s;                                        /* mainly for legacy use */
+    struct rfapi_rib_key        key;
+  } u;
+  uint32_t                     lifetime;
+  uint8_t                      cost;
+  struct rfapi_l2address_option        l2o;
+};
 
 struct rfapi_info
 {
@@ -151,4 +172,16 @@ rfapiRibCheckCounts (
 #define RFAPI_RIB_CHECK_COUNTS(checkstats, offset)
 #endif
 
+extern void
+rfapi_rib_key_init (struct prefix        *prefix, /* may be NULL */
+                    struct prefix_rd     *rd,     /* may be NULL */
+                    struct prefix        *aux,    /* may be NULL */
+                    struct rfapi_rib_key *rk);
+
+extern int
+rfapi_rib_key_cmp (void *k1, void *k2);
+
+extern void
+rfapiAdbFree (struct rfapi_adb *adb);
+
 #endif /* QUAGGA_HGP_RFAPI_RIB_H */
index 572ca7f0a6b1e8254453f374affe0c4e6c8682ee..1118cfd76f304b3fc90f1cd57dbebafd034d1ea0 100644 (file)
@@ -1846,14 +1846,14 @@ rfapiPrintDescriptor (struct vty *vty, struct rfapi_descriptor *rfd)
         {
 
           /* group like family prefixes together in output */
-          if (family != adb->prefix_ip.family)
+          if (family != adb->u.s.prefix_ip.family)
             continue;
 
-          prefix2str (&adb->prefix_ip, buf, BUFSIZ);
+          prefix2str (&adb->u.s.prefix_ip, buf, BUFSIZ);
           buf[BUFSIZ - 1] = 0;  /* guarantee NUL-terminated */
 
           vty_out (vty, "  Adv Pfx: %s%s", buf, HVTY_NEWLINE);
-          rfapiPrintAdvertisedInfo (vty, rfd, SAFI_MPLS_VPN, &adb->prefix_ip);
+          rfapiPrintAdvertisedInfo (vty, rfd, SAFI_MPLS_VPN, &adb->u.s.prefix_ip);
         }
     }
   for (rc =
@@ -1864,14 +1864,14 @@ rfapiPrintDescriptor (struct vty *vty, struct rfapi_descriptor *rfd)
                       &cursor))
     {
 
-      prefix2str (&adb->prefix_eth, buf, BUFSIZ);
+      prefix2str (&adb->u.s.prefix_eth, buf, BUFSIZ);
       buf[BUFSIZ - 1] = 0;      /* guarantee NUL-terminated */
 
       vty_out (vty, "  Adv Pfx: %s%s", buf, HVTY_NEWLINE);
 
       /* TBD update the following function to print ethernet info */
       /* Also need to pass/use rd */
-      rfapiPrintAdvertisedInfo (vty, rfd, SAFI_MPLS_VPN, &adb->prefix_ip);
+      rfapiPrintAdvertisedInfo (vty, rfd, SAFI_MPLS_VPN, &adb->u.s.prefix_ip);
     }
   vty_out (vty, "%s", HVTY_NEWLINE);
 }
@@ -3363,7 +3363,7 @@ rfapiDeleteLocalPrefixes (struct rfapi_local_reg_delete_arg *cda)
 
             if (pPrefix)
               {
-                if (!prefix_same (pPrefix, &adb->prefix_ip))
+                if (!prefix_same (pPrefix, &adb->u.s.prefix_ip))
                   {
 #if DEBUG_L2_EXTRA
                     vnc_zlog_debug_verbose ("%s: adb=%p, prefix doesn't match, skipping",
@@ -3376,7 +3376,7 @@ rfapiDeleteLocalPrefixes (struct rfapi_local_reg_delete_arg *cda)
               {
                 if (memcmp
                     (cda->l2o.o.macaddr.octet,
-                     adb->prefix_eth.u.prefix_eth.octet, ETHER_ADDR_LEN))
+                     adb->u.s.prefix_eth.u.prefix_eth.octet, ETHER_ADDR_LEN))
                   {
 #if DEBUG_L2_EXTRA
                     vnc_zlog_debug_verbose ("%s: adb=%p, macaddr doesn't match, skipping",
@@ -3418,24 +3418,23 @@ rfapiDeleteLocalPrefixes (struct rfapi_local_reg_delete_arg *cda)
 
             this_advertisement_prefix_count = 1;
 
-            rfapiQprefix2Rprefix (&adb->prefix_ip, &rp);
+            rfapiQprefix2Rprefix (&adb->u.s.prefix_ip, &rp);
 
             /* if mac addr present in advert,  make l2o vn option */
-            if (adb->prefix_eth.family == AF_ETHERNET)
+            if (adb->u.s.prefix_eth.family == AF_ETHERNET)
               {
-
                 memset (&vn1, 0, sizeof (vn1));
                 memset (&vn2, 0, sizeof (vn2));
 
                 vn1.type = RFAPI_VN_OPTION_TYPE_L2ADDR;
-                vn1.v.l2addr.macaddr = adb->prefix_eth.u.prefix_eth;
+                vn1.v.l2addr.macaddr = adb->u.s.prefix_eth.u.prefix_eth;
 
                 /*
                  * use saved RD value instead of trying to invert
                  * complex L2-style RD computation in rfapi_register()
                  */
                 vn2.type = RFAPI_VN_OPTION_TYPE_INTERNAL_RD;
-                vn2.v.internal_rd = adb->prd;
+                vn2.v.internal_rd = adb->u.s.prd;
 
                 vn1.next = &vn2;
 
@@ -3487,7 +3486,7 @@ rfapiDeleteLocalPrefixes (struct rfapi_local_reg_delete_arg *cda)
                 if (CHECK_FLAG (cda->l2o.flags, RFAPI_L2O_MACADDR))
                   {
                     if (memcmp (cda->l2o.o.macaddr.octet,
-                                adb->prefix_eth.u.prefix_eth.octet,
+                                adb->u.s.prefix_eth.u.prefix_eth.octet,
                                 ETHER_ADDR_LEN))
                       {
 
@@ -3514,7 +3513,7 @@ rfapiDeleteLocalPrefixes (struct rfapi_local_reg_delete_arg *cda)
 
                 struct rfapi_vn_option vn;
 
-                rfapiQprefix2Rprefix (&adb->prefix_ip, &rp);
+                rfapiQprefix2Rprefix (&adb->u.s.prefix_ip, &rp);
 
                 memset (&vn, 0, sizeof (vn));
                 vn.type = RFAPI_VN_OPTION_TYPE_L2ADDR;