Fix IP feature ordering. 79/5779/4
authorNeale Ranns <nranns@cisco.com>
Thu, 16 Mar 2017 19:49:09 +0000 (15:49 -0400)
committerDamjan Marion <dmarion.lists@gmail.com>
Fri, 17 Mar 2017 19:41:56 +0000 (19:41 +0000)
Drop comes before lookup when enabled. is_first_or_last is not required when setting a feature, the anchor is added in find_config_with_features().
Don't make the PG interfaces automatically L3 enabled, this way we can have tests that check the L3 protocol disbaled behaviour.

Change-Id: Icef22a920b27ff9cec6ab2da6b05f05c532cb60f
Signed-off-by: Neale Ranns <nranns@cisco.com>
12 files changed:
src/vnet/devices/devices.c
src/vnet/feature/feature.c
src/vnet/feature/feature.h
src/vnet/interface_output.c
src/vnet/ip/ip4_forward.c
src/vnet/pg/stream.c
test/test_ip4.py
test/test_ip6.py
test/test_ip_mcast.py
test/test_mpls.py
test/vpp_interface.py
test/vpp_ip_route.py

index c81043c..38f3002 100644 (file)
@@ -55,7 +55,6 @@ VNET_FEATURE_ARC_INIT (device_input, static) =
 {
   .arc_name  = "device-input",
   .start_nodes = VNET_FEATURES ("device-input"),
-  .end_node = "ethernet-input",
   .arc_index_ptr = &feature_main.device_input_feature_arc_index,
 };
 
index 5a4be02..f0e9004 100644 (file)
@@ -109,9 +109,6 @@ vnet_feature_init (vlib_main_t * vm)
          freg = freg->next;
        }
 
-      cm->end_feature_index =
-       vnet_get_feature_index (arc_index, areg->end_node);
-
       /* next */
       areg = areg->next;
       arc_index++;
@@ -185,7 +182,6 @@ vnet_feature_enable_disable_with_index (u8 arc_index, u32 feature_index,
   vnet_feature_main_t *fm = &feature_main;
   vnet_feature_config_main_t *cm;
   i16 feature_count;
-  int is_first_or_last;
   u32 ci;
 
   if (arc_index == (u8) ~ 0)
@@ -214,19 +210,8 @@ vnet_feature_enable_disable_with_index (u8 arc_index, u32 feature_index,
   /* update feature count */
   enable_disable = (enable_disable > 0);
   feature_count += enable_disable ? 1 : -1;
-  is_first_or_last = (feature_count == enable_disable);
   ASSERT (feature_count >= 0);
 
-  if (is_first_or_last && cm->end_feature_index != ~0)
-    {
-      /*register end node */
-      ci = (enable_disable
-           ? vnet_config_add_feature
-           : vnet_config_del_feature)
-       (vlib_get_main (), &cm->config_main, ci, cm->end_feature_index, 0, 0);
-      cm->config_index_by_sw_if_index[sw_if_index] = ci;
-    }
-
   fm->sw_if_index_has_features[arc_index] =
     clib_bitmap_set (fm->sw_if_index_has_features[arc_index], sw_if_index,
                     (feature_count > 0));
index 77b1499..7ec43ea 100644 (file)
@@ -30,8 +30,6 @@ typedef struct _vnet_feature_arc_registration
   /** Start nodes */
   char **start_nodes;
   int n_start_nodes;
-  /** End node */
-  char *end_node;
   /* Feature arc index, assigned by init function */
   u8 feature_arc_index;
   u8 *arc_index_ptr;
@@ -66,7 +64,6 @@ typedef struct vnet_feature_config_main_t_
 {
   vnet_config_main_t config_main;
   u32 *config_index_by_sw_if_index;
-  u32 end_feature_index;
 } vnet_feature_config_main_t;
 
 typedef struct
index abac50b..03f2cdc 100644 (file)
@@ -1258,7 +1258,6 @@ VNET_FEATURE_ARC_INIT (interface_output, static) =
 {
   .arc_name  = "interface-output",
   .start_nodes = VNET_FEATURES (0),
-  .end_node = "interface-tx",
   .arc_index_ptr = &vnet_main.interface_main.output_feature_arc_index,
 };
 
index 34bc6c5..0dad61d 100644 (file)
@@ -847,9 +847,8 @@ ip4_sw_interface_enable_disable (u32 sw_if_index, u32 is_enable)
                               !is_enable, 0, 0);
 
 
-  vnet_feature_enable_disable ("ip4-multicast",
-                              "ip4-mfib-forward-lookup",
-                              sw_if_index, is_enable, 0, 0);
+  vnet_feature_enable_disable ("ip4-multicast", "ip4-drop",
+                              sw_if_index, !is_enable, 0, 0);
 }
 
 static clib_error_t *
@@ -954,7 +953,6 @@ VNET_FEATURE_ARC_INIT (ip4_unicast, static) =
 {
   .arc_name = "ip4-unicast",
   .start_nodes = VNET_FEATURES ("ip4-input", "ip4-input-no-checksum"),
-  .end_node = "ip4-lookup",
   .arc_index_ptr = &ip4_main.lookup_main.ucast_feature_arc_index,
 };
 
@@ -1021,27 +1019,25 @@ VNET_FEATURE_INIT (ip4_vxlan_bypass, static) =
   .runs_before = VNET_FEATURES ("ip4-lookup"),
 };
 
-VNET_FEATURE_INIT (ip4_lookup, static) =
+VNET_FEATURE_INIT (ip4_drop, static) =
 {
   .arc_name = "ip4-unicast",
-  .node_name = "ip4-lookup",
-  .runs_before = VNET_FEATURES ("ip4-drop"),
+  .node_name = "ip4-drop",
+  .runs_before = VNET_FEATURES ("ip4-lookup"),
 };
 
-VNET_FEATURE_INIT (ip4_drop, static) =
+VNET_FEATURE_INIT (ip4_lookup, static) =
 {
   .arc_name = "ip4-unicast",
-  .node_name = "ip4-drop",
+  .node_name = "ip4-lookup",
   .runs_before = 0,    /* not before any other features */
 };
 
-
 /* Built-in ip4 multicast rx feature path definition */
 VNET_FEATURE_ARC_INIT (ip4_multicast, static) =
 {
   .arc_name = "ip4-multicast",
   .start_nodes = VNET_FEATURES ("ip4-input", "ip4-input-no-checksum"),
-  .end_node = "ip4-lookup-multicast",
   .arc_index_ptr = &ip4_main.lookup_main.mcast_feature_arc_index,
 };
 
@@ -1052,17 +1048,17 @@ VNET_FEATURE_INIT (ip4_vpath_mc, static) =
   .runs_before = VNET_FEATURES ("ip4-mfib-forward-lookup"),
 };
 
-VNET_FEATURE_INIT (ip4_lookup_mc, static) =
+VNET_FEATURE_INIT (ip4_mc_drop, static) =
 {
   .arc_name = "ip4-multicast",
-  .node_name = "ip4-mfib-forward-lookup",
-  .runs_before = VNET_FEATURES ("ip4-drop"),
+  .node_name = "ip4-drop",
+  .runs_before = VNET_FEATURES ("ip4-mfib-forward-lookup"),
 };
 
-VNET_FEATURE_INIT (ip4_mc_drop, static) =
+VNET_FEATURE_INIT (ip4_lookup_mc, static) =
 {
   .arc_name = "ip4-multicast",
-  .node_name = "ip4-drop",
+  .node_name = "ip4-mfib-forward-lookup",
   .runs_before = 0,    /* last feature */
 };
 
@@ -1071,7 +1067,6 @@ VNET_FEATURE_ARC_INIT (ip4_output, static) =
 {
   .arc_name = "ip4-output",
   .start_nodes = VNET_FEATURES ("ip4-rewrite", "ip4-midchain"),
-  .end_node = "interface-output",
   .arc_index_ptr = &ip4_main.lookup_main.output_feature_arc_index,
 };
 
index 560c4b0..05d820a 100644 (file)
@@ -223,10 +223,6 @@ pg_interface_add_or_get (pg_main_t * pg, uword if_id)
                                              CLIB_CACHE_LINE_BYTES);
          *pi->lockp = 0;
        }
-
-      ip4_sw_interface_enable_disable (pi->hw_if_index, 1);
-      ip6_sw_interface_enable_disable (pi->hw_if_index, 1);
-      mpls_sw_interface_enable_disable (&mpls_main, pi->hw_if_index, 1);
     }
 
   return i;
index 7f6e92f..79af549 100644 (file)
@@ -5,7 +5,8 @@ import unittest
 
 from framework import VppTestCase, VppTestRunner
 from vpp_sub_interface import VppSubInterface, VppDot1QSubint, VppDot1ADSubint
-from vpp_ip_route import VppIpRoute, VppRoutePath
+from vpp_ip_route import VppIpRoute, VppRoutePath, VppIpMRoute, \
+    VppMRoutePath, MRouteItfFlags, MRouteEntryFlags
 
 from scapy.packet import Raw
 from scapy.layers.l2 import Ether, Dot1Q
@@ -546,5 +547,101 @@ class TestIPNull(VppTestCase):
         self.assertEqual(icmp.dst, "10.0.0.2")
 
 
+class TestIPDisabled(VppTestCase):
+    """ IPv4 disabled """
+
+    def setUp(self):
+        super(TestIPDisabled, self).setUp()
+
+        # create 2 pg interfaces
+        self.create_pg_interfaces(range(2))
+
+        # PG0 is IP enalbed
+        self.pg0.admin_up()
+        self.pg0.config_ip4()
+        self.pg0.resolve_arp()
+
+        # PG 1 is not IP enabled
+        self.pg1.admin_up()
+
+    def tearDown(self):
+        super(TestIPDisabled, self).tearDown()
+        for i in self.pg_interfaces:
+            i.unconfig_ip4()
+            i.admin_down()
+
+    def send_and_assert_no_replies(self, intf, pkts, remark):
+        intf.add_stream(pkts)
+        self.pg_enable_capture(self.pg_interfaces)
+        self.pg_start()
+        for i in self.pg_interfaces:
+            i.get_capture(0)
+            i.assert_nothing_captured(remark=remark)
+
+    def test_ip_disabled(self):
+        """ IP Disabled """
+
+        #
+        # An (S,G).
+        # one accepting interface, pg0, 2 forwarding interfaces
+        #
+        route_232_1_1_1 = VppIpMRoute(
+            self,
+            "0.0.0.0",
+            "232.1.1.1", 32,
+            MRouteEntryFlags.MFIB_ENTRY_FLAG_NONE,
+            [VppMRoutePath(self.pg1.sw_if_index,
+                           MRouteItfFlags.MFIB_ITF_FLAG_ACCEPT),
+             VppMRoutePath(self.pg0.sw_if_index,
+                           MRouteItfFlags.MFIB_ITF_FLAG_FORWARD)])
+        route_232_1_1_1.add_vpp_config()
+
+        pu = (Ether(src=self.pg1.remote_mac,
+                    dst=self.pg1.local_mac) /
+              IP(src="10.10.10.10", dst=self.pg0.remote_ip4) /
+              UDP(sport=1234, dport=1234) /
+              Raw('\xa5' * 100))
+        pm = (Ether(src=self.pg1.remote_mac,
+                    dst=self.pg1.local_mac) /
+              IP(src="10.10.10.10", dst="232.1.1.1") /
+              UDP(sport=1234, dport=1234) /
+              Raw('\xa5' * 100))
+
+        #
+        # PG1 does not forward IP traffic
+        #
+        self.send_and_assert_no_replies(self.pg1, pu, "IP disabled")
+        self.send_and_assert_no_replies(self.pg1, pm, "IP disabled")
+
+        #
+        # IP enable PG1
+        #
+        self.pg1.config_ip4()
+
+        #
+        # Now we get packets through
+        #
+        self.pg1.add_stream(pu)
+        self.pg_enable_capture(self.pg_interfaces)
+        self.pg_start()
+        rx = self.pg0.get_capture(1)
+
+        self.pg1.add_stream(pm)
+        self.pg_enable_capture(self.pg_interfaces)
+        self.pg_start()
+        rx = self.pg0.get_capture(1)
+
+        #
+        # Disable PG1
+        #
+        self.pg1.unconfig_ip4()
+
+        #
+        # PG1 does not forward IP traffic
+        #
+        self.send_and_assert_no_replies(self.pg1, pu, "IP disabled")
+        self.send_and_assert_no_replies(self.pg1, pm, "IP disabled")
+
+
 if __name__ == '__main__':
     unittest.main(testRunner=VppTestRunner)
index e57e034..a8e8d4d 100644 (file)
@@ -6,7 +6,8 @@ from socket import AF_INET6
 from framework import VppTestCase, VppTestRunner
 from vpp_sub_interface import VppSubInterface, VppDot1QSubint
 from vpp_pg_interface import is_ipv6_misc
-from vpp_ip_route import VppIpRoute, VppRoutePath, find_route
+from vpp_ip_route import VppIpRoute, VppRoutePath, find_route, VppIpMRoute, \
+    VppMRoutePath, MRouteItfFlags, MRouteEntryFlags
 from vpp_neighbor import find_nbr, VppNeighbor
 
 from scapy.packet import Raw
@@ -981,5 +982,102 @@ class TestIPNull(VppTestCase):
         self.assertEqual(icmp.code, 1)
 
 
+class TestIPDisabled(VppTestCase):
+    """ IPv6 disabled """
+
+    def setUp(self):
+        super(TestIPDisabled, self).setUp()
+
+        # create 2 pg interfaces
+        self.create_pg_interfaces(range(2))
+
+        # PG0 is IP enalbed
+        self.pg0.admin_up()
+        self.pg0.config_ip6()
+        self.pg0.resolve_ndp()
+
+        # PG 1 is not IP enabled
+        self.pg1.admin_up()
+
+    def tearDown(self):
+        super(TestIPDisabled, self).tearDown()
+        for i in self.pg_interfaces:
+            i.unconfig_ip4()
+            i.admin_down()
+
+    def send_and_assert_no_replies(self, intf, pkts, remark):
+        intf.add_stream(pkts)
+        self.pg_enable_capture(self.pg_interfaces)
+        self.pg_start()
+        for i in self.pg_interfaces:
+            i.get_capture(0)
+            i.assert_nothing_captured(remark=remark)
+
+    def test_ip_disabled(self):
+        """ IP Disabled """
+
+        #
+        # An (S,G).
+        # one accepting interface, pg0, 2 forwarding interfaces
+        #
+        route_ff_01 = VppIpMRoute(
+            self,
+            "::",
+            "ffef::1", 128,
+            MRouteEntryFlags.MFIB_ENTRY_FLAG_NONE,
+            [VppMRoutePath(self.pg1.sw_if_index,
+                           MRouteItfFlags.MFIB_ITF_FLAG_ACCEPT),
+             VppMRoutePath(self.pg0.sw_if_index,
+                           MRouteItfFlags.MFIB_ITF_FLAG_FORWARD)],
+            is_ip6=1)
+        route_ff_01.add_vpp_config()
+
+        pu = (Ether(src=self.pg1.remote_mac,
+                    dst=self.pg1.local_mac) /
+              IPv6(src="2001::1", dst=self.pg0.remote_ip6) /
+              UDP(sport=1234, dport=1234) /
+              Raw('\xa5' * 100))
+        pm = (Ether(src=self.pg1.remote_mac,
+                    dst=self.pg1.local_mac) /
+              IPv6(src="2001::1", dst="ffef::1") /
+              UDP(sport=1234, dport=1234) /
+              Raw('\xa5' * 100))
+
+        #
+        # PG1 does not forward IP traffic
+        #
+        self.send_and_assert_no_replies(self.pg1, pu, "IPv6 disabled")
+        self.send_and_assert_no_replies(self.pg1, pm, "IPv6 disabled")
+
+        #
+        # IP enable PG1
+        #
+        self.pg1.config_ip6()
+
+        #
+        # Now we get packets through
+        #
+        self.pg1.add_stream(pu)
+        self.pg_enable_capture(self.pg_interfaces)
+        self.pg_start()
+        rx = self.pg0.get_capture(1)
+
+        self.pg1.add_stream(pm)
+        self.pg_enable_capture(self.pg_interfaces)
+        self.pg_start()
+        rx = self.pg0.get_capture(1)
+
+        #
+        # Disable PG1
+        #
+        self.pg1.unconfig_ip6()
+
+        #
+        # PG1 does not forward IP traffic
+        #
+        self.send_and_assert_no_replies(self.pg1, pu, "IPv6 disabled")
+        self.send_and_assert_no_replies(self.pg1, pm, "IPv6 disabled")
+
+
 if __name__ == '__main__':
     unittest.main(testRunner=VppTestRunner)
index 864cb80..094942b 100644 (file)
@@ -4,7 +4,8 @@ import unittest
 
 from framework import VppTestCase, VppTestRunner
 from vpp_sub_interface import VppSubInterface, VppDot1QSubint, VppDot1ADSubint
-from vpp_ip_route import VppIpMRoute, VppMRoutePath, VppMFibSignal
+from vpp_ip_route import VppIpMRoute, VppMRoutePath, VppMFibSignal, \
+    MRouteItfFlags, MRouteEntryFlags
 
 from scapy.packet import Raw
 from scapy.layers.l2 import Ether
@@ -12,23 +13,6 @@ from scapy.layers.inet import IP, UDP, getmacbyip, ICMP
 from scapy.layers.inet6 import IPv6, getmacbyip6
 from util import ppp
 
-
-class MRouteItfFlags:
-    MFIB_ITF_FLAG_NONE = 0
-    MFIB_ITF_FLAG_NEGATE_SIGNAL = 1
-    MFIB_ITF_FLAG_ACCEPT = 2
-    MFIB_ITF_FLAG_FORWARD = 4
-    MFIB_ITF_FLAG_SIGNAL_PRESENT = 8
-    MFIB_ITF_FLAG_INTERNAL_COPY = 16
-
-
-class MRouteEntryFlags:
-    MFIB_ENTRY_FLAG_NONE = 0
-    MFIB_ENTRY_FLAG_SIGNAL = 1
-    MFIB_ENTRY_FLAG_DROP = 2
-    MFIB_ENTRY_FLAG_CONNECTED = 4
-    MFIB_ENTRY_FLAG_INHERIT_ACCEPT = 8
-
 #
 # The number of packets sent is set to 90 so that when we replicate more than 3
 # times, which we do for some entries, we will generate more than 256 packets
index 9082637..fc83264 100644 (file)
@@ -738,5 +738,88 @@ class TestMPLS(VppTestCase):
         route_35_eos.remove_vpp_config()
         route_34_eos.remove_vpp_config()
 
+
+class TestMPLSDisabled(VppTestCase):
+    """ MPLS disabled """
+
+    def setUp(self):
+        super(TestMPLSDisabled, self).setUp()
+
+        # create 2 pg interfaces
+        self.create_pg_interfaces(range(2))
+
+        # PG0 is MPLS enalbed
+        self.pg0.admin_up()
+        self.pg0.config_ip4()
+        self.pg0.resolve_arp()
+        self.pg0.enable_mpls()
+
+        # PG 1 is not MPLS enabled
+        self.pg1.admin_up()
+
+    def tearDown(self):
+        super(TestMPLSDisabled, self).tearDown()
+        for i in self.pg_interfaces:
+            i.unconfig_ip4()
+            i.admin_down()
+
+    def send_and_assert_no_replies(self, intf, pkts, remark):
+        intf.add_stream(pkts)
+        self.pg_enable_capture(self.pg_interfaces)
+        self.pg_start()
+        for i in self.pg_interfaces:
+            i.get_capture(0)
+            i.assert_nothing_captured(remark=remark)
+
+    def test_mpls_disabled(self):
+        """ MPLS Disabled """
+
+        tx = (Ether(src=self.pg1.remote_mac,
+                    dst=self.pg1.local_mac) /
+              MPLS(label=32, ttl=64) /
+              IPv6(src="2001::1", dst=self.pg0.remote_ip6) /
+              UDP(sport=1234, dport=1234) /
+              Raw('\xa5' * 100))
+
+        #
+        # A simple MPLS xconnect - eos label in label out
+        #
+        route_32_eos = VppMplsRoute(self, 32, 1,
+                                    [VppRoutePath(self.pg0.remote_ip4,
+                                                  self.pg0.sw_if_index,
+                                                  labels=[33])])
+        route_32_eos.add_vpp_config()
+
+        #
+        # PG1 does not forward IP traffic
+        #
+        self.send_and_assert_no_replies(self.pg1, tx, "MPLS disabled")
+
+        #
+        # MPLS enable PG1
+        #
+        self.pg1.enable_mpls()
+
+        #
+        # Now we get packets through
+        #
+        self.pg1.add_stream(tx)
+        self.pg_enable_capture(self.pg_interfaces)
+        self.pg_start()
+
+        rx = self.pg0.get_capture(1)
+
+        #
+        # Disable PG1
+        #
+        self.pg1.disable_mpls()
+
+        #
+        # PG1 does not forward IP traffic
+        #
+        self.send_and_assert_no_replies(self.pg1, tx, "IPv6 disabled")
+        self.send_and_assert_no_replies(self.pg1, tx, "IPv6 disabled")
+
+
 if __name__ == '__main__':
     unittest.main(testRunner=VppTestRunner)
index aeaf27a..5dba097 100644 (file)
@@ -321,6 +321,11 @@ class VppInterface(object):
         self.test.vapi.sw_interface_enable_disable_mpls(
             self.sw_if_index)
 
+    def disable_mpls(self):
+        """Enable MPLS on the VPP interface."""
+        self.test.vapi.sw_interface_enable_disable_mpls(
+            self.sw_if_index, 0)
+
     def is_ip4_entry_in_fib_dump(self, dump):
         for i in dump:
             if i.address == self.local_ip4n and \
index e1c2b4b..faf5f80 100644 (file)
@@ -12,6 +12,23 @@ MPLS_IETF_MAX_LABEL = 0xfffff
 MPLS_LABEL_INVALID = MPLS_IETF_MAX_LABEL + 1
 
 
+class MRouteItfFlags:
+    MFIB_ITF_FLAG_NONE = 0
+    MFIB_ITF_FLAG_NEGATE_SIGNAL = 1
+    MFIB_ITF_FLAG_ACCEPT = 2
+    MFIB_ITF_FLAG_FORWARD = 4
+    MFIB_ITF_FLAG_SIGNAL_PRESENT = 8
+    MFIB_ITF_FLAG_INTERNAL_COPY = 16
+
+
+class MRouteEntryFlags:
+    MFIB_ENTRY_FLAG_NONE = 0
+    MFIB_ENTRY_FLAG_SIGNAL = 1
+    MFIB_ENTRY_FLAG_DROP = 2
+    MFIB_ENTRY_FLAG_CONNECTED = 4
+    MFIB_ENTRY_FLAG_INHERIT_ACCEPT = 8
+
+
 def find_route(test, ip_addr, len, table_id=0, inet=AF_INET):
     if inet == AF_INET:
         s = 4