X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=test%2Ftest_dhcp.py;h=3d00f1b846800dfab350a5ef27ea4701c58e5fc8;hb=8006c6a;hp=b3bd3a1d3cd4a0c79298a5da50c653810e542db4;hpb=4585eb86c54afd21d5aa264e947020a041656064;p=vpp.git diff --git a/test/test_dhcp.py b/test/test_dhcp.py index b3bd3a1d3cd..3d00f1b8468 100644 --- a/test/test_dhcp.py +++ b/test/test_dhcp.py @@ -8,7 +8,6 @@ from framework import VppTestCase, VppTestRunner, running_extended_tests from vpp_neighbor import VppNeighbor from vpp_ip_route import find_route, VppIpTable from util import mk_ll_addr - from scapy.layers.l2 import Ether, getmacbyip, ARP from scapy.layers.inet import IP, UDP, ICMP from scapy.layers.inet6 import IPv6, in6_getnsmac @@ -20,7 +19,7 @@ from scapy.layers.dhcp6 import DHCP6, DHCP6_Solicit, DHCP6_RelayForward, \ from socket import AF_INET, AF_INET6 from scapy.utils import inet_pton, inet_ntop from scapy.utils6 import in6_ptop -from util import mactobinary +from vpp_papi import mac_pton DHCP4_CLIENT_PORT = 68 DHCP4_SERVER_PORT = 67 @@ -1195,7 +1194,6 @@ class TestDHCP(VppTestCase): self.pg4.unconfig_ip6() self.pg5.unconfig_ip6() - @unittest.skipUnless(running_extended_tests(), "part of extended tests") def test_dhcp_client(self): """ DHCP Client""" @@ -1218,10 +1216,12 @@ class TestDHCP(VppTestCase): p_offer = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) / IP(src=self.pg3.remote_ip4, dst="255.255.255.255") / UDP(sport=DHCP4_SERVER_PORT, dport=DHCP4_CLIENT_PORT) / - BOOTP(op=1, yiaddr=self.pg3.local_ip4) / + BOOTP(op=1, + yiaddr=self.pg3.local_ip4, + chaddr=mac_pton(self.pg3.local_mac)) / DHCP(options=[('message-type', 'offer'), ('server_id', self.pg3.remote_ip4), - ('end')])) + 'end'])) self.pg3.add_stream(p_offer) self.pg_enable_capture(self.pg_interfaces) @@ -1232,18 +1232,19 @@ class TestDHCP(VppTestCase): self.pg3.local_ip4) # - # Send an acknowloedgement + # Send an acknowledgment # p_ack = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) / IP(src=self.pg3.remote_ip4, dst="255.255.255.255") / UDP(sport=DHCP4_SERVER_PORT, dport=DHCP4_CLIENT_PORT) / - BOOTP(op=1, yiaddr=self.pg3.local_ip4) / + BOOTP(op=1, yiaddr=self.pg3.local_ip4, + chaddr=mac_pton(self.pg3.local_mac)) / DHCP(options=[('message-type', 'ack'), ('subnet_mask', "255.255.255.0"), ('router', self.pg3.remote_ip4), ('server_id', self.pg3.remote_ip4), ('lease_time', 43200), - ('end')])) + 'end'])) self.pg3.add_stream(p_ack) self.pg_enable_capture(self.pg_interfaces) @@ -1266,7 +1267,7 @@ class TestDHCP(VppTestCase): # remove the left over ARP entry self.vapi.ip_neighbor_add_del(self.pg3.sw_if_index, - mactobinary(self.pg3.remote_mac), + mac_pton(self.pg3.remote_mac), self.pg3.remote_ip4, is_add=0) # @@ -1294,6 +1295,11 @@ class TestDHCP(VppTestCase): self.verify_orig_dhcp_discover(rx[0], self.pg3, hostname, self.pg3.local_mac) + # TODO: VPP DHCP client should not accept DHCP OFFER message with + # the XID (Transaction ID) not matching the XID of the most recent + # DHCP DISCOVERY message. + # Such DHCP OFFER message must be silently discarded - RFC2131. + # Reported in Jira ticket: VPP-99 self.pg3.add_stream(p_offer) self.pg_enable_capture(self.pg_interfaces) self.pg_start() @@ -1308,13 +1314,14 @@ class TestDHCP(VppTestCase): p_ack = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) / IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) / UDP(sport=DHCP4_SERVER_PORT, dport=DHCP4_CLIENT_PORT) / - BOOTP(op=1, yiaddr=self.pg3.local_ip4) / + BOOTP(op=1, yiaddr=self.pg3.local_ip4, + chaddr=mac_pton(self.pg3.local_mac)) / DHCP(options=[('message-type', 'ack'), ('subnet_mask', "255.255.255.0"), ('router', self.pg3.remote_ip4), ('server_id', self.pg3.remote_ip4), ('lease_time', 43200), - ('end')])) + 'end'])) self.pg3.add_stream(p_ack) self.pg_enable_capture(self.pg_interfaces) @@ -1365,10 +1372,11 @@ class TestDHCP(VppTestCase): p_offer = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) / IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) / UDP(sport=DHCP4_SERVER_PORT, dport=DHCP4_CLIENT_PORT) / - BOOTP(op=1, yiaddr=self.pg3.local_ip4) / + BOOTP(op=1, yiaddr=self.pg3.local_ip4, + chaddr=mac_pton(self.pg3.local_mac)) / DHCP(options=[('message-type', 'offer'), ('server_id', self.pg3.remote_ip4), - ('end')])) + 'end'])) self.pg3.add_stream(p_offer) self.pg_enable_capture(self.pg_interfaces) @@ -1380,18 +1388,19 @@ class TestDHCP(VppTestCase): broadcast=0) # - # Send an acknowloedgement + # Send an acknowledgment # p_ack = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) / IP(src=self.pg3.remote_ip4, dst=self.pg3.local_ip4) / UDP(sport=DHCP4_SERVER_PORT, dport=DHCP4_CLIENT_PORT) / - BOOTP(op=1, yiaddr=self.pg3.local_ip4) / + BOOTP(op=1, yiaddr=self.pg3.local_ip4, + chaddr=mac_pton(self.pg3.local_mac)) / DHCP(options=[('message-type', 'ack'), ('subnet_mask', "255.255.255.0"), ('router', self.pg3.remote_ip4), ('server_id', self.pg3.remote_ip4), ('lease_time', 43200), - ('end')])) + 'end'])) self.pg3.add_stream(p_ack) self.pg_enable_capture(self.pg_interfaces) @@ -1414,9 +1423,32 @@ class TestDHCP(VppTestCase): # remove the left over ARP entry self.vapi.ip_neighbor_add_del(self.pg3.sw_if_index, - mactobinary(self.pg3.remote_mac), + mac_pton(self.pg3.remote_mac), self.pg3.remote_ip4, is_add=0) + + # + # read the DHCP client details from a dump + # + clients = self.vapi.dhcp_client_dump() + + self.assertEqual(clients[0].client.sw_if_index, + self.pg3.sw_if_index) + self.assertEqual(clients[0].lease.sw_if_index, + self.pg3.sw_if_index) + self.assertEqual(clients[0].client.hostname.rstrip('\0'), + hostname) + self.assertEqual(clients[0].lease.hostname.rstrip('\0'), + hostname) + self.assertEqual(clients[0].lease.is_ipv6, 0) + # 0 = DISCOVER, 1 = REQUEST, 2 = BOUND + self.assertEqual(clients[0].lease.state, 2) + self.assertEqual(clients[0].lease.mask_width, 24) + self.assertEqual(clients[0].lease.router_address.rstrip('\0'), + self.pg3.remote_ip4n) + self.assertEqual(clients[0].lease.host_address.rstrip('\0'), + self.pg3.local_ip4n) + # # remove the DHCP config # @@ -1428,6 +1460,96 @@ class TestDHCP(VppTestCase): self.assertFalse(find_route(self, self.pg3.local_ip4, 32)) self.assertFalse(find_route(self, self.pg3.local_ip4, 24)) + # + # Start the procedure again. Use requested lease time option. + # + self.pg3.admin_down() + self.sleep(1) + self.pg3.admin_up() + self.vapi.dhcp_client(self.pg3.sw_if_index, hostname) + + rx = self.pg3.get_capture(1) + + self.verify_orig_dhcp_discover(rx[0], self.pg3, hostname) + + # + # Send back on offer with requested lease time, expect the request + # + lease_time = 1 + p_offer = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) / + IP(src=self.pg3.remote_ip4, dst='255.255.255.255') / + UDP(sport=DHCP4_SERVER_PORT, dport=DHCP4_CLIENT_PORT) / + BOOTP(op=1, + yiaddr=self.pg3.local_ip4, + chaddr=mac_pton(self.pg3.local_mac)) / + DHCP(options=[('message-type', 'offer'), + ('server_id', self.pg3.remote_ip4), + ('lease_time', lease_time), + 'end'])) + + self.pg3.add_stream(p_offer) + self.pg_enable_capture(self.pg_interfaces) + self.pg_start() + + rx = self.pg3.get_capture(1) + self.verify_orig_dhcp_request(rx[0], self.pg3, hostname, + self.pg3.local_ip4) + + # + # Send an acknowledgment + # + p_ack = (Ether(dst=self.pg3.local_mac, src=self.pg3.remote_mac) / + IP(src=self.pg3.remote_ip4, dst='255.255.255.255') / + UDP(sport=DHCP4_SERVER_PORT, dport=DHCP4_CLIENT_PORT) / + BOOTP(op=1, yiaddr=self.pg3.local_ip4, + chaddr=mac_pton(self.pg3.local_mac)) / + DHCP(options=[('message-type', 'ack'), + ('subnet_mask', '255.255.255.0'), + ('router', self.pg3.remote_ip4), + ('server_id', self.pg3.remote_ip4), + ('lease_time', lease_time), + 'end'])) + + self.pg3.add_stream(p_ack) + self.pg_enable_capture(self.pg_interfaces) + self.pg_start() + + # + # We'll get an ARP request for the router address + # + rx = self.pg3.get_capture(1) + + self.assertEqual(rx[0][ARP].pdst, self.pg3.remote_ip4) + + # + # At the end of this procedure there should be a connected route + # in the FIB + # + self.assertTrue(find_route(self, self.pg3.local_ip4, 32)) + self.assertTrue(find_route(self, self.pg3.local_ip4, 24)) + + # remove the left over ARP entry + self.vapi.ip_neighbor_add_del(self.pg3.sw_if_index, + mac_pton(self.pg3.remote_mac), + self.pg3.remote_ip4, + is_add=0) + + # + # Sleep for the lease time + # + self.sleep(lease_time+1) + + # + # And now the route should be gone + # + self.assertFalse(find_route(self, self.pg3.local_ip4, 32)) + self.assertFalse(find_route(self, self.pg3.local_ip4, 24)) + + # + # remove the DHCP config + # + self.vapi.dhcp_client(self.pg3.sw_if_index, hostname, is_add=0) + if __name__ == '__main__': unittest.main(testRunner=VppTestRunner)