Fix IP feature ordering.

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>
This commit is contained in:
Neale Ranns
2017-03-16 15:49:09 -04:00
committed by Damjan Marion
parent 696e88da97
commit 180279b912
12 changed files with 320 additions and 65 deletions

View 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,
};

View 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));

View 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

View 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,
};

View 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) =
{
.arc_name = "ip4-unicast",
.node_name = "ip4-lookup",
.runs_before = VNET_FEATURES ("ip4-drop"),
};
VNET_FEATURE_INIT (ip4_drop, static) =
{
.arc_name = "ip4-unicast",
.node_name = "ip4-drop",
.runs_before = 0, /* not before any other features */
.runs_before = VNET_FEATURES ("ip4-lookup"),
};
VNET_FEATURE_INIT (ip4_lookup, static) =
{
.arc_name = "ip4-unicast",
.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) =
{
.arc_name = "ip4-multicast",
.node_name = "ip4-mfib-forward-lookup",
.runs_before = VNET_FEATURES ("ip4-drop"),
};
VNET_FEATURE_INIT (ip4_mc_drop, static) =
{
.arc_name = "ip4-multicast",
.node_name = "ip4-drop",
.runs_before = VNET_FEATURES ("ip4-mfib-forward-lookup"),
};
VNET_FEATURE_INIT (ip4_lookup_mc, static) =
{
.arc_name = "ip4-multicast",
.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,
};

View 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;

View 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)

View 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)

View 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

View 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)

View 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 \

View 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