X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=test%2Ftest_dhcp.py;h=39133a35bd1321d7a03f0c1a28f67c0975ed075e;hb=daff1784037376f4a5caec2f5975f9b5fc23d5a4;hp=db7a7cc223ca26fc3c01a03ef119ead8c22c1442;hpb=52fae862646e25bac6d1cd11b9fc7ac77299bc25;p=vpp.git diff --git a/test/test_dhcp.py b/test/test_dhcp.py index db7a7cc223c..39133a35bd1 100644 --- a/test/test_dhcp.py +++ b/test/test_dhcp.py @@ -11,7 +11,8 @@ 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, in6_mactoifaceid +from scapy.layers.inet6 import IPv6, in6_getnsmac +from scapy.utils6 import in6_mactoifaceid from scapy.layers.dhcp import DHCP, BOOTP, DHCPTypes from scapy.layers.dhcp6 import DHCP6, DHCP6_Solicit, DHCP6_RelayForward, \ DHCP6_RelayReply, DHCP6_Advertise, DHCP6OptRelayMsg, DHCP6OptIfaceId, \ @@ -214,7 +215,8 @@ class TestDHCP(VppTestCase): self.assertEqual(udp.dport, DHCP4_SERVER_PORT) self.assertEqual(udp.sport, DHCP4_CLIENT_PORT) - def verify_orig_dhcp_discover(self, pkt, intf, hostname, client_id=None): + def verify_orig_dhcp_discover(self, pkt, intf, hostname, client_id=None, + broadcast=1): self.verify_orig_dhcp_pkt(pkt, intf) self.verify_dhcp_msg_type(pkt, "discover") @@ -224,9 +226,13 @@ class TestDHCP(VppTestCase): bootp = pkt[BOOTP] self.assertEqual(bootp.ciaddr, "0.0.0.0") self.assertEqual(bootp.giaddr, "0.0.0.0") - self.assertEqual(bootp.flags, 0x8000) + if broadcast: + self.assertEqual(bootp.flags, 0x8000) + else: + self.assertEqual(bootp.flags, 0x0000) - def verify_orig_dhcp_request(self, pkt, intf, hostname, ip): + def verify_orig_dhcp_request(self, pkt, intf, hostname, ip, + broadcast=1): self.verify_orig_dhcp_pkt(pkt, intf) self.verify_dhcp_msg_type(pkt, "request") @@ -235,7 +241,10 @@ class TestDHCP(VppTestCase): bootp = pkt[BOOTP] self.assertEqual(bootp.ciaddr, "0.0.0.0") self.assertEqual(bootp.giaddr, "0.0.0.0") - self.assertEqual(bootp.flags, 0x8000) + if broadcast: + self.assertEqual(bootp.flags, 0x8000) + else: + self.assertEqual(bootp.flags, 0x0000) def verify_relayed_dhcp_discover(self, pkt, intf, src_intf=None, fib_id=0, oui=0, @@ -1208,7 +1217,9 @@ 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=mactobinary(self.pg3.local_mac)) / DHCP(options=[('message-type', 'offer'), ('server_id', self.pg3.remote_ip4), ('end')])) @@ -1227,7 +1238,8 @@ class TestDHCP(VppTestCase): 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=mactobinary(self.pg3.local_mac)) / DHCP(options=[('message-type', 'ack'), ('subnet_mask', "255.255.255.0"), ('router', self.pg3.remote_ip4), @@ -1298,7 +1310,8 @@ 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=mactobinary(self.pg3.local_mac)) / DHCP(options=[('message-type', 'ack'), ('subnet_mask', "255.255.255.0"), ('router', self.pg3.remote_ip4), @@ -1310,6 +1323,14 @@ class TestDHCP(VppTestCase): 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) + self.pg_enable_capture(self.pg_interfaces) + # # At the end of this procedure there should be a connected route # in the FIB @@ -1325,6 +1346,116 @@ class TestDHCP(VppTestCase): self.assertFalse(find_route(self, self.pg3.local_ip4, 32)) self.assertFalse(find_route(self, self.pg3.local_ip4, 24)) + # + # Rince and repeat, this time with VPP configured not to set + # the braodcast flag in the discover and request messages, + # and for the server to unicast the responses. + # + # Configure DHCP client on PG3 and capture the discover sent + # + self.vapi.dhcp_client(self.pg3.sw_if_index, hostname, + set_broadcast_flag=0) + + rx = self.pg3.get_capture(1) + + self.verify_orig_dhcp_discover(rx[0], self.pg3, hostname, + broadcast=0) + + # + # Send back on offer, unicasted to the offered address. + # Expect the request. + # + 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, + chaddr=mactobinary(self.pg3.local_mac)) / + DHCP(options=[('message-type', 'offer'), + ('server_id', self.pg3.remote_ip4), + ('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, + broadcast=0) + + # + # Send an acknowloedgement + # + 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, + chaddr=mactobinary(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')])) + + 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) + self.pg_enable_capture(self.pg_interfaces) + + # + # At the end of this procedure there should be a connected route + # in the FIB + # + self.assertTrue(find_route(self, self.pg3.local_ip4, 24)) + self.assertTrue(find_route(self, self.pg3.local_ip4, 32)) + + # remove the left over ARP entry + self.vapi.ip_neighbor_add_del(self.pg3.sw_if_index, + mactobinary(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 + # + self.vapi.dhcp_client(self.pg3.sw_if_index, hostname, is_add=0) + + # + # 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)) + if __name__ == '__main__': unittest.main(testRunner=VppTestRunner)