IP route update fix when multipath and drop set 14/14714/2
authorNeale Ranns <nranns@cisco.com>
Fri, 7 Sep 2018 08:48:54 +0000 (01:48 -0700)
committerDamjan Marion <dmarion@me.com>
Fri, 7 Sep 2018 11:16:14 +0000 (11:16 +0000)
Change-Id: I9cec7486cb6e3c5261d74d2b15a4d19469285a30
Signed-off-by: Neale Ranns <nranns@cisco.com>
src/vnet/ip/ip_api.c
src/vpp/api/custom_dump.c
test/test_ip4.py
test/vpp_ip_route.py

index 7217f9d..31b7e40 100644 (file)
@@ -839,26 +839,6 @@ add_del_route_t_handler (u8 is_multipath,
 
   path.frp_flags = path_flags;
 
-  if (is_multipath)
-    {
-      stats_dslock_with_hint (1 /* release hint */ , 10 /* tag */ );
-
-
-      vec_add1 (paths, path);
-
-      if (is_add)
-       fib_table_entry_path_add2 (fib_index,
-                                  prefix,
-                                  FIB_SOURCE_API, entry_flags, paths);
-      else
-       fib_table_entry_path_remove2 (fib_index,
-                                     prefix, FIB_SOURCE_API, paths);
-
-      vec_free (paths);
-      stats_dsunlock ();
-      return 0;
-    }
-
   stats_dslock_with_hint (1 /* release hint */ , 2 /* tag */ );
 
   if (is_drop || is_local || is_classify || is_unreach || is_prohibit)
@@ -914,6 +894,20 @@ add_del_route_t_handler (u8 is_multipath,
          fib_table_entry_special_remove (fib_index, prefix, FIB_SOURCE_API);
        }
     }
+  else if (is_multipath)
+    {
+      vec_add1 (paths, path);
+
+      if (is_add)
+       fib_table_entry_path_add2 (fib_index,
+                                  prefix,
+                                  FIB_SOURCE_API, entry_flags, paths);
+      else
+       fib_table_entry_path_remove2 (fib_index,
+                                     prefix, FIB_SOURCE_API, paths);
+
+      vec_free (paths);
+    }
   else
     {
       if (is_add)
index 2a8cd78..57268a9 100644 (file)
@@ -758,15 +758,28 @@ static void *vl_api_ip_add_del_route_t_print
   if (mp->is_multipath)
     s = format (s, "multipath ");
 
-  if (mp->is_multipath)
-    s = format (s, "multipath ");
-
   if (mp->next_hop_table_id)
     s = format (s, "lookup-in-vrf %d ", ntohl (mp->next_hop_table_id));
 
   FINISH;
 }
 
+static void *vl_api_ip_table_add_del_t_print
+  (vl_api_ip_table_add_del_t * mp, void *handle)
+{
+  u8 *s;
+
+  s = format (0, "SCRIPT: ip_table_add_del ");
+  if (!mp->is_add)
+    s = format (s, "del ");
+  if (mp->is_ipv6)
+    s = format (s, "ip6 ");
+  if (mp->table_id != 0)
+    s = format (s, "vrf %d ", ntohl (mp->table_id));
+
+  FINISH;
+}
+
 static void *vl_api_proxy_arp_add_del_t_print
   (vl_api_proxy_arp_add_del_t * mp, void *handle)
 {
@@ -3560,6 +3573,7 @@ _(TAP_CREATE_V2, tap_create_v2)                                         \
 _(TAP_DELETE_V2, tap_delete_v2)                                         \
 _(SW_INTERFACE_TAP_V2_DUMP, sw_interface_tap_v2_dump)                   \
 _(IP_ADD_DEL_ROUTE, ip_add_del_route)                                   \
+_(IP_TABLE_ADD_DEL, ip_table_add_del)                                   \
 _(PROXY_ARP_ADD_DEL, proxy_arp_add_del)                                 \
 _(PROXY_ARP_INTFC_ENABLE_DISABLE, proxy_arp_intfc_enable_disable)       \
 _(MPLS_TUNNEL_ADD_DEL, mpls_tunnel_add_del)                            \
index d15453d..02a31be 100644 (file)
@@ -552,7 +552,7 @@ class TestIPNull(VppTestCase):
         super(TestIPNull, self).setUp()
 
         # create 2 pg interfaces
-        self.create_pg_interfaces(range(1))
+        self.create_pg_interfaces(range(2))
 
         for i in self.pg_interfaces:
             i.admin_up()
@@ -624,6 +624,32 @@ class TestIPNull(VppTestCase):
         self.assertEqual(icmp.src, self.pg0.remote_ip4)
         self.assertEqual(icmp.dst, "10.0.0.2")
 
+    def test_ip_drop(self):
+        """ IP Drop Routes """
+
+        p = (Ether(src=self.pg0.remote_mac,
+                   dst=self.pg0.local_mac) /
+             IP(src=self.pg0.remote_ip4, dst="1.1.1.1") /
+             UDP(sport=1234, dport=1234) /
+             Raw('\xa5' * 100))
+
+        r1 = VppIpRoute(self, "1.1.1.0", 24,
+                        [VppRoutePath(self.pg1.remote_ip4,
+                                      self.pg1.sw_if_index)])
+        r1.add_vpp_config()
+
+        rx = self.send_and_expect(self.pg0, p * 65, self.pg1)
+
+        #
+        # insert a more specific as a drop
+        #
+        r2 = VppIpRoute(self, "1.1.1.1", 32, [], is_drop=1)
+        r2.add_vpp_config()
+
+        self.send_and_assert_no_replies(self.pg0, p * 65, "Drop Route")
+        r2.remove_vpp_config()
+        rx = self.send_and_expect(self.pg0, p * 65, self.pg1)
+
 
 class TestIPDisabled(VppTestCase):
     """ IPv4 disabled """
index 9e5c531..216f5c7 100644 (file)
@@ -223,7 +223,7 @@ class VppIpRoute(VppObject):
 
     def __init__(self, test, dest_addr,
                  dest_addr_len, paths, table_id=0, is_ip6=0, is_local=0,
-                 is_unreach=0, is_prohibit=0):
+                 is_unreach=0, is_prohibit=0, is_drop=0):
         self._test = test
         self.paths = paths
         self.dest_addr_len = dest_addr_len
@@ -232,6 +232,7 @@ class VppIpRoute(VppObject):
         self.is_local = is_local
         self.is_unreach = is_unreach
         self.is_prohibit = is_prohibit
+        self.is_drop = is_drop
         self.dest_addr_p = dest_addr
         if is_ip6:
             self.dest_addr = inet_pton(AF_INET6, dest_addr)
@@ -246,7 +247,8 @@ class VppIpRoute(VppObject):
         self.is_prohibit = is_prohibit
 
     def add_vpp_config(self):
-        if self.is_local or self.is_unreach or self.is_prohibit:
+        if self.is_local or self.is_unreach or \
+           self.is_prohibit or self.is_drop:
             self._test.vapi.ip_add_del_route(
                 self.dest_addr,
                 self.dest_addr_len,
@@ -255,6 +257,7 @@ class VppIpRoute(VppObject):
                 is_local=self.is_local,
                 is_unreach=self.is_unreach,
                 is_prohibit=self.is_prohibit,
+                is_drop=self.is_drop,
                 table_id=self.table_id,
                 is_ipv6=self.is_ip6)
         else:
@@ -282,7 +285,8 @@ class VppIpRoute(VppObject):
         self._test.registry.register(self, self._test.logger)
 
     def remove_vpp_config(self):
-        if self.is_local or self.is_unreach or self.is_prohibit:
+        if self.is_local or self.is_unreach or \
+           self.is_prohibit or self.is_drop:
             self._test.vapi.ip_add_del_route(
                 self.dest_addr,
                 self.dest_addr_len,