fib: Set the GLEAN flag on attached export routes so that the SAS works 72/33072/4
authorNeale Ranns <neale@graphiant.com>
Fri, 9 Jul 2021 13:03:52 +0000 (13:03 +0000)
committerDamjan Marion <dmarion@me.com>
Tue, 13 Jul 2021 19:26:07 +0000 (19:26 +0000)
correctly.

Type: fix

Signed-off-by: Neale Ranns <neale@graphiant.com>
Change-Id: I4bc2eb394a8f9d01c5a12de2ce963c22209d5439

src/vnet/fib/fib_entry_src.c
src/vnet/fib/fib_table.c
src/vnet/fib/fib_types.c
src/vnet/fib/fib_types.h
test/test_gbp.py
test/test_neighbor.py

index 1285734..a4a4f1a 100644 (file)
@@ -1497,52 +1497,34 @@ static inline int
 fib_route_attached_cross_table (const fib_entry_t *fib_entry,
                                const fib_route_path_t *rpath)
 {
-    /*
-     * - All zeros next-hop
-     * - a valid interface
-     * - entry's fib index not equeal to interface's index
-     */
-    if (ip46_address_is_zero(&rpath->frp_addr) &&
-       (~0 != rpath->frp_sw_if_index) &&
-        !(rpath->frp_flags & (FIB_ROUTE_PATH_DVR | FIB_ROUTE_PATH_UDP_ENCAP)) &&
-       (fib_entry->fe_fib_index != 
-        fib_table_get_index_for_sw_if_index(fib_entry_get_proto(fib_entry),
-                                            rpath->frp_sw_if_index)))
-    {
-       return (!0);
-    }
-    return (0);
-}
+    const fib_prefix_t *pfx = &fib_entry->fe_prefix;
 
-/*
- * Return true if the path is attached
- */
-static inline int
-fib_path_is_attached (const fib_route_path_t *rpath)
-{
-    /*
-     * DVR paths are not attached, since we are not playing the
-     * L3 game with these
-     */
-    if (rpath->frp_flags & FIB_ROUTE_PATH_DVR)
+    switch (pfx->fp_proto)
     {
-        return (0);
+    case FIB_PROTOCOL_MPLS:
+        /* MPLS routes are never imported/exported */
+       return (0);
+    case FIB_PROTOCOL_IP6:
+        /* Ignore link local addresses these also can't be imported/exported */
+        if (ip6_address_is_link_local_unicast (&pfx->fp_addr.ip6))
+        {
+            return (!0);
+        }
+        break;
+    case FIB_PROTOCOL_IP4:
+        break;
     }
 
     /*
-     * - All zeros next-hop
-     * - a valid interface
+     * an attached path and entry's fib index not equal to interface's index
      */
-    if (ip46_address_is_zero(&rpath->frp_addr) &&
-       (~0 != rpath->frp_sw_if_index))
+    if (fib_route_path_is_attached(rpath) &&
+       fib_entry->fe_fib_index !=
+        fib_table_get_index_for_sw_if_index(fib_entry_get_proto(fib_entry),
+                                            rpath->frp_sw_if_index))
     {
        return (!0);
     }
-    else if (rpath->frp_flags & FIB_ROUTE_PATH_ATTACHED ||
-             rpath->frp_flags & FIB_ROUTE_PATH_GLEAN)
-    {
-        return (!0);
-    }
     return (0);
 }
 
@@ -1580,7 +1562,7 @@ fib_entry_flags_update (const fib_entry_t *fib_entry,
         if ((esrc->fes_src == FIB_SOURCE_API) ||
             (esrc->fes_src == FIB_SOURCE_CLI))
         {
-            if (fib_path_is_attached(rpath))
+            if (fib_route_path_is_attached(rpath))
             {
                 esrc->fes_entry_flags |= FIB_ENTRY_FLAG_ATTACHED;
             }
index eaeee5b..7cc989d 100644 (file)
@@ -531,6 +531,11 @@ fib_table_route_path_fixup (const fib_prefix_t *prefix,
             fib_prefix_normalize(prefix, &path->frp_connected);
         }
     }
+    else if (fib_route_path_is_attached(path))
+    {
+        path->frp_flags |= FIB_ROUTE_PATH_GLEAN;
+        fib_prefix_normalize(prefix, &path->frp_connected);
+    }
     if (*eflags & FIB_ENTRY_FLAG_DROP)
     {
        path->frp_flags |= FIB_ROUTE_PATH_DROP;
index e2b8df7..eab5ca2 100644 (file)
@@ -752,3 +752,36 @@ unformat_fib_route_path (unformat_input_t * input, va_list * args)
 
     return (1);
 }
+
+/*
+ * Return true if the path is attached
+ */
+int
+fib_route_path_is_attached (const fib_route_path_t *rpath)
+{
+    /*
+     * DVR paths are not attached, since we are not playing the
+     * L3 game with these
+     */
+    if (rpath->frp_flags & (FIB_ROUTE_PATH_DVR |
+                            FIB_ROUTE_PATH_UDP_ENCAP))
+    {
+        return (0);
+    }
+
+    /*
+     * - All zeros next-hop
+     * - a valid interface
+     */
+    if (ip46_address_is_zero(&rpath->frp_addr) &&
+       (~0 != rpath->frp_sw_if_index))
+    {
+       return (!0);
+    }
+    else if (rpath->frp_flags & FIB_ROUTE_PATH_ATTACHED ||
+             rpath->frp_flags & FIB_ROUTE_PATH_GLEAN)
+    {
+        return (!0);
+    }
+    return (0);
+}
index 18362e0..55b404b 100644 (file)
@@ -619,6 +619,11 @@ extern uword unformat_fib_route_path(unformat_input_t * input, va_list * args);
  */
 extern u8 * format_fib_route_path(u8 *s, va_list *ap);
 
+/*
+ * Return true if the path is attached
+ */
+extern int fib_route_path_is_attached (const fib_route_path_t *rpath);
+
 /**
  * A help string to list the FIB path options
  */
index 21d0770..c30a729 100644 (file)
@@ -1004,7 +1004,7 @@ class TestGBP(VppTestCase):
             self.logger.info(self.vapi.cli("sh gbp endpoint"))
 
             # ... results in a Gratuitous ARP/ND on the EPG's uplink
-            rx = ep.epg.uplink.get_capture(len(ep.ips), timeout=0.2)
+            rx = ep.epg.uplink.get_capture(len(ep.ips) + 1, timeout=0.2)
 
             for ii, ip in enumerate(ep.ips):
                 p = rx[ii]
index c34ac1a..b33a70b 100644 (file)
@@ -1811,6 +1811,19 @@ class ARPTestCase(VppTestCase):
                                 "10.0.1.2",
                                 "10.0.1.128")
 
+        # apply a connected prefix to an interface in a different table
+        VppIpRoute(self, "10.0.1.0", 24,
+                   [VppRoutePath("0.0.0.0",
+                                 self.pg1.sw_if_index)],
+                   table_id=1).add_vpp_config()
+
+        rxs = self.send_and_expect(self.pg3, [p2], self.pg1)
+        for rx in rxs:
+            self.verify_arp_req(rx,
+                                self.pg1.local_mac,
+                                "10.0.1.2",
+                                "10.0.1.128")
+
         # cleanup
         conn3.remove_vpp_config()
         conn2.remove_vpp_config()