summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/vnet/fib/fib_entry_src.c58
-rw-r--r--src/vnet/fib/fib_table.c5
-rw-r--r--src/vnet/fib/fib_types.c33
-rw-r--r--src/vnet/fib/fib_types.h5
-rw-r--r--test/test_gbp.py2
-rw-r--r--test/test_neighbor.py13
6 files changed, 77 insertions, 39 deletions
diff --git a/src/vnet/fib/fib_entry_src.c b/src/vnet/fib/fib_entry_src.c
index 12857347a9f..a4a4f1ae0b5 100644
--- a/src/vnet/fib/fib_entry_src.c
+++ b/src/vnet/fib/fib_entry_src.c
@@ -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;
}
diff --git a/src/vnet/fib/fib_table.c b/src/vnet/fib/fib_table.c
index eaeee5bb921..7cc989d6324 100644
--- a/src/vnet/fib/fib_table.c
+++ b/src/vnet/fib/fib_table.c
@@ -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;
diff --git a/src/vnet/fib/fib_types.c b/src/vnet/fib/fib_types.c
index e2b8df79e63..eab5ca22571 100644
--- a/src/vnet/fib/fib_types.c
+++ b/src/vnet/fib/fib_types.c
@@ -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);
+}
diff --git a/src/vnet/fib/fib_types.h b/src/vnet/fib/fib_types.h
index 18362e0965d..55b404b044e 100644
--- a/src/vnet/fib/fib_types.h
+++ b/src/vnet/fib/fib_types.h
@@ -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
*/
diff --git a/test/test_gbp.py b/test/test_gbp.py
index 21d0770cf66..c30a729519d 100644
--- a/test/test_gbp.py
+++ b/test/test_gbp.py
@@ -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]
diff --git a/test/test_neighbor.py b/test/test_neighbor.py
index c34ac1aea4e..b33a70b2a3c 100644
--- a/test/test_neighbor.py
+++ b/test/test_neighbor.py
@@ -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()