X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=test%2Ftest_ip4.py;h=e501bff3fecb63dd71c84dd0acb867b7c09bca40;hb=1855b8e4;hp=42fd1164a5f8dcb2694475cd8b050efe6e9fef79;hpb=054c03ac9c20a5e38121590b83f01fd91f82acf0;p=vpp.git diff --git a/test/test_ip4.py b/test/test_ip4.py index 42fd1164a5f..e501bff3fec 100644 --- a/test/test_ip4.py +++ b/test/test_ip4.py @@ -36,7 +36,6 @@ class TestIPv4(VppTestCase): :ivar list interfaces: pg interfaces and subinterfaces. :ivar dict flows: IPv4 packet flows in test. - :ivar list pg_if_packet_sizes: packet sizes in test. """ super(TestIPv4, self).setUp() @@ -55,8 +54,7 @@ class TestIPv4(VppTestCase): self.flows[self.pg2.sub_if] = [self.pg0, self.pg1.sub_if] # packet sizes - self.pg_if_packet_sizes = [64, 512, 1518, 9018] - self.sub_if_packet_sizes = [64, 512, 1518 + 4, 9018 + 4] + self.pg_if_packet_sizes = [64, 1500, 9020] self.interfaces = list(self.pg_interfaces) self.interfaces.extend(self.sub_interfaces) @@ -103,34 +101,52 @@ class TestIPv4(VppTestCase): (count, percent)) percent += 1 - def create_stream(self, src_if, packet_sizes): + def modify_packet(self, src_if, packet_size, pkt): + """Add load, set destination IP and extend packet to required packet + size for defined interface. + + :param VppInterface src_if: Interface to create packet for. + :param int packet_size: Required packet size. + :param Scapy pkt: Packet to be modified. + """ + dst_if_idx = packet_size / 10 % 2 + dst_if = self.flows[src_if][dst_if_idx] + info = self.create_packet_info(src_if, dst_if) + payload = self.info_to_payload(info) + p = pkt/Raw(payload) + p[IP].dst = dst_if.remote_ip4 + info.data = p.copy() + if isinstance(src_if, VppSubInterface): + p = src_if.add_dot1_layer(p) + self.extend_packet(p, packet_size) + + return p + + def create_stream(self, src_if): """Create input packet stream for defined interface. :param VppInterface src_if: Interface to create packet stream for. - :param list packet_sizes: Required packet sizes. """ - pkts = [] - for i in range(0, 257): - dst_if = self.flows[src_if][i % 2] - info = self.create_packet_info(src_if, dst_if) - payload = self.info_to_payload(info) - p = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) / - IP(src=src_if.remote_ip4, dst=dst_if.remote_ip4) / - UDP(sport=1234, dport=1234) / - Raw(payload)) - info.data = p.copy() - if isinstance(src_if, VppSubInterface): - p = src_if.add_dot1_layer(p) - size = packet_sizes[(i // 2) % len(packet_sizes)] - self.extend_packet(p, size) - pkts.append(p) + hdr_ext = 4 if isinstance(src_if, VppSubInterface) else 0 + pkt_tmpl = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) / + IP(src=src_if.remote_ip4) / + UDP(sport=1234, dport=1234)) + + pkts = [self.modify_packet(src_if, i, pkt_tmpl) + for i in xrange(self.pg_if_packet_sizes[0], + self.pg_if_packet_sizes[1], 10)] + pkts_b = [self.modify_packet(src_if, i, pkt_tmpl) + for i in xrange(self.pg_if_packet_sizes[1] + hdr_ext, + self.pg_if_packet_sizes[2] + hdr_ext, 50)] + pkts.extend(pkts_b) + return pkts def verify_capture(self, dst_if, capture): """Verify captured input packet stream for defined interface. :param VppInterface dst_if: Interface to verify captured packet stream - for. + for. :param list capture: Captured packet stream. """ self.logger.info("Verifying capture on interface %s" % dst_if.name) @@ -183,15 +199,15 @@ class TestIPv4(VppTestCase): Test scenario: - Create IPv4 stream for pg0 interface - - Create IPv4 tagged streams for pg1's and pg2's subinterface. + - Create IPv4 tagged streams for pg1's and pg2's sub-interface. - Send and verify received packets on each interface. """ - pkts = self.create_stream(self.pg0, self.pg_if_packet_sizes) + pkts = self.create_stream(self.pg0) self.pg0.add_stream(pkts) for i in self.sub_interfaces: - pkts = self.create_stream(i, self.sub_if_packet_sizes) + pkts = self.create_stream(i) i.parent.add_stream(pkts) self.pg_enable_capture(self.pg_interfaces) @@ -205,6 +221,66 @@ class TestIPv4(VppTestCase): self.verify_capture(i, pkts) +class TestICMPEcho(VppTestCase): + """ ICMP Echo Test Case """ + + def setUp(self): + super(TestICMPEcho, self).setUp() + + # create 1 pg interface + self.create_pg_interfaces(range(1)) + + for i in self.pg_interfaces: + i.admin_up() + i.config_ip4() + i.resolve_arp() + + def tearDown(self): + super(TestICMPEcho, self).tearDown() + for i in self.pg_interfaces: + i.unconfig_ip4() + i.admin_down() + + def test_icmp_echo(self): + """ VPP replies to ICMP Echo Request + + Test scenario: + + - Receive ICMP Echo Request message on pg0 interface. + - Check outgoing ICMP Echo Reply message on pg0 interface. + """ + + icmp_id = 0xb + icmp_seq = 5 + icmp_load = '\x0a' * 18 + p_echo_request = (Ether(src=self.pg0.remote_mac, + dst=self.pg0.local_mac) / + IP(src=self.pg0.remote_ip4, dst=self.pg0.local_ip4) / + ICMP(id=icmp_id, seq=icmp_seq) / + Raw(load=icmp_load)) + + self.pg0.add_stream(p_echo_request) + self.pg_enable_capture(self.pg_interfaces) + self.pg_start() + + rx = self.pg0.get_capture(1) + rx = rx[0] + ether = rx[Ether] + ipv4 = rx[IP] + icmp = rx[ICMP] + + self.assertEqual(ether.src, self.pg0.local_mac) + self.assertEqual(ether.dst, self.pg0.remote_mac) + + self.assertEqual(ipv4.src, self.pg0.local_ip4) + self.assertEqual(ipv4.dst, self.pg0.remote_ip4) + + self.assertEqual(icmptypes[icmp.type], "echo-reply") + self.assertEqual(icmp.id, icmp_id) + self.assertEqual(icmp.seq, icmp_seq) + self.assertEqual(icmp[Raw].load, icmp_load) + + class TestIPv4FibCrud(VppTestCase): """ FIB - add/update/delete - ip4 routes @@ -572,14 +648,6 @@ class TestIPDisabled(VppTestCase): 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 """ @@ -667,14 +735,6 @@ class TestIPSubNets(VppTestCase): for i in self.pg_interfaces: 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_sub_nets(self): """ IP Sub Nets """ @@ -985,12 +1045,6 @@ class TestIPVlan0(VppTestCase): i.admin_down() super(TestIPVlan0, self).tearDown() - def send_and_expect(self, input, pkts, output): - input.add_stream(pkts) - self.pg_enable_capture(self.pg_interfaces) - self.pg_start() - rx = output.get_capture(len(pkts)) - def test_ip_vlan_0(self): """ IP VLAN-0 """ @@ -1028,23 +1082,6 @@ class TestIPPunt(VppTestCase): i.unconfig_ip4() i.admin_down() - def send_and_expect(self, input, pkts, output): - self.vapi.cli("clear trace") - input.add_stream(pkts) - self.pg_enable_capture(self.pg_interfaces) - self.pg_start() - rx = output.get_capture(len(pkts)) - return rx - - def send_and_assert_no_replies(self, intf, pkts, remark): - self.vapi.cli("clear trace") - 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_punt(self): """ IP punt police and redirect """ @@ -1138,23 +1175,6 @@ class TestIPDeag(VppTestCase): i.unconfig_ip4() i.admin_down() - def send_and_expect(self, input, pkts, output): - self.vapi.cli("clear trace") - input.add_stream(pkts) - self.pg_enable_capture(self.pg_interfaces) - self.pg_start() - rx = output.get_capture(len(pkts)) - return rx - - def send_and_assert_no_replies(self, intf, pkts, remark): - self.vapi.cli("clear trace") - 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_deag(self): """ IP Deag Routes """ @@ -1227,5 +1247,219 @@ class TestIPDeag(VppTestCase): self.send_and_expect(self.pg0, pkts_src, self.pg2) +class TestIPInput(VppTestCase): + """ IPv4 Input Exceptions """ + + def setUp(self): + super(TestIPInput, self).setUp() + + self.create_pg_interfaces(range(2)) + + for i in self.pg_interfaces: + i.admin_up() + i.config_ip4() + i.resolve_arp() + + def tearDown(self): + super(TestIPInput, self).tearDown() + for i in self.pg_interfaces: + i.unconfig_ip4() + i.admin_down() + + def test_ip_input(self): + """ IP Input Exceptions """ + + # i can't find a way in scapy to construct an IP packet + # with a length less than the IP header length + + # + # Packet too short - this is forwarded + # + p_short = (Ether(src=self.pg0.remote_mac, + dst=self.pg0.local_mac) / + IP(src=self.pg0.remote_ip4, + dst=self.pg1.remote_ip4, + len=40) / + UDP(sport=1234, dport=1234) / + Raw('\xa5' * 100)) + + rx = self.send_and_expect(self.pg0, p_short * 65, self.pg1) + + # + # Packet too long - this is dropped + # + p_long = (Ether(src=self.pg0.remote_mac, + dst=self.pg0.local_mac) / + IP(src=self.pg0.remote_ip4, + dst=self.pg1.remote_ip4, + len=400) / + UDP(sport=1234, dport=1234) / + Raw('\xa5' * 100)) + + rx = self.send_and_assert_no_replies(self.pg0, p_long * 65, + "too long") + + # + # bad chksum - this is dropped + # + p_chksum = (Ether(src=self.pg0.remote_mac, + dst=self.pg0.local_mac) / + IP(src=self.pg0.remote_ip4, + dst=self.pg1.remote_ip4, + chksum=400) / + UDP(sport=1234, dport=1234) / + Raw('\xa5' * 100)) + + rx = self.send_and_assert_no_replies(self.pg0, p_chksum * 65, + "bad checksum") + + # + # bad version - this is dropped + # + p_ver = (Ether(src=self.pg0.remote_mac, + dst=self.pg0.local_mac) / + IP(src=self.pg0.remote_ip4, + dst=self.pg1.remote_ip4, + version=3) / + UDP(sport=1234, dport=1234) / + Raw('\xa5' * 100)) + + rx = self.send_and_assert_no_replies(self.pg0, p_ver * 65, + "funky version") + + # + # fragment offset 1 - this is dropped + # + p_frag = (Ether(src=self.pg0.remote_mac, + dst=self.pg0.local_mac) / + IP(src=self.pg0.remote_ip4, + dst=self.pg1.remote_ip4, + frag=1) / + UDP(sport=1234, dport=1234) / + Raw('\xa5' * 100)) + + rx = self.send_and_assert_no_replies(self.pg0, p_frag * 65, + "frag offset") + + # + # TTL expired packet + # + p_ttl = (Ether(src=self.pg0.remote_mac, + dst=self.pg0.local_mac) / + IP(src=self.pg0.remote_ip4, + dst=self.pg1.remote_ip4, + ttl=1) / + UDP(sport=1234, dport=1234) / + Raw('\xa5' * 100)) + + rx = self.send_and_expect(self.pg0, p_ttl * 65, self.pg0) + + rx = rx[0] + icmp = rx[ICMP] + + self.assertEqual(icmptypes[icmp.type], "time-exceeded") + self.assertEqual(icmpcodes[icmp.type][icmp.code], + "ttl-zero-during-transit") + self.assertEqual(icmp.src, self.pg0.remote_ip4) + self.assertEqual(icmp.dst, self.pg1.remote_ip4) + + # + # MTU exceeded + # + p_mtu = (Ether(src=self.pg0.remote_mac, + dst=self.pg0.local_mac) / + IP(src=self.pg0.remote_ip4, + dst=self.pg1.remote_ip4, + ttl=10, flags='DF') / + UDP(sport=1234, dport=1234) / + Raw('\xa5' * 2000)) + + self.vapi.sw_interface_set_mtu(self.pg1.sw_if_index, [1500, 0, 0, 0]) + + rx = self.send_and_expect(self.pg0, p_mtu * 65, self.pg0) + rx = rx[0] + icmp = rx[ICMP] + + self.assertEqual(icmptypes[icmp.type], "dest-unreach") + self.assertEqual(icmpcodes[icmp.type][icmp.code], + "fragmentation-needed") + self.assertEqual(icmp.src, self.pg0.remote_ip4) + self.assertEqual(icmp.dst, self.pg1.remote_ip4) + + self.vapi.sw_interface_set_mtu(self.pg1.sw_if_index, [2500, 0, 0, 0]) + rx = self.send_and_expect(self.pg0, p_mtu * 65, self.pg1) + + # Reset MTU for subsequent tests + self.vapi.sw_interface_set_mtu(self.pg1.sw_if_index, [9000, 0, 0, 0]) + + +class TestIPDirectedBroadcast(VppTestCase): + """ IPv4 Directed Broadcast """ + + def setUp(self): + super(TestIPDirectedBroadcast, self).setUp() + + self.create_pg_interfaces(range(2)) + + for i in self.pg_interfaces: + i.admin_up() + + def tearDown(self): + super(TestIPDirectedBroadcast, self).tearDown() + for i in self.pg_interfaces: + i.admin_down() + + def test_ip_input(self): + """ IP Directed Broadcast """ + + # + # set the directed broadcast on pg0 first, then config IP4 addresses + # for pg1 directed broadcast is always disabled + self.vapi.sw_interface_set_ip_directed_broadcast( + self.pg0.sw_if_index, 1) + + p0 = (Ether(src=self.pg1.remote_mac, + dst=self.pg1.local_mac) / + IP(src="1.1.1.1", + dst=self.pg0._local_ip4_bcast) / + UDP(sport=1234, dport=1234) / + Raw('\xa5' * 2000)) + p1 = (Ether(src=self.pg0.remote_mac, + dst=self.pg0.local_mac) / + IP(src="1.1.1.1", + dst=self.pg1._local_ip4_bcast) / + UDP(sport=1234, dport=1234) / + Raw('\xa5' * 2000)) + + self.pg0.config_ip4() + self.pg0.resolve_arp() + self.pg1.config_ip4() + self.pg1.resolve_arp() + + # + # test packet is L2 broadcast + # + rx = self.send_and_expect(self.pg1, p0 * 65, self.pg0) + self.assertTrue(rx[0][Ether].dst, "ff:ff:ff:ff:ff:ff") + + self.send_and_assert_no_replies(self.pg0, p1 * 65, + "directed broadcast disabled") + + # + # toggle directed broadcast on pg0 + # + self.vapi.sw_interface_set_ip_directed_broadcast( + self.pg0.sw_if_index, 0) + self.send_and_assert_no_replies(self.pg1, p0 * 65, + "directed broadcast disabled") + + self.vapi.sw_interface_set_ip_directed_broadcast( + self.pg0.sw_if_index, 1) + rx = self.send_and_expect(self.pg1, p0 * 65, self.pg0) + + self.pg0.unconfig_ip4() + self.pg1.unconfig_ip4() + + if __name__ == '__main__': unittest.main(testRunner=VppTestRunner)