1 from socket import AF_INET6
3 from scapy.layers.dhcp6 import DHCP6_Advertise, DHCP6OptClientId, \
4 DHCP6OptStatusCode, DHCP6OptPref, DHCP6OptIA_PD, DHCP6OptIAPrefix, \
5 DHCP6OptServerId, DHCP6_Solicit, DHCP6_Reply, DHCP6_Request, DHCP6_Renew, \
6 DHCP6_Rebind, DUID_LL, DHCP6_Release, DHCP6OptElapsedTime, DHCP6OptIA_NA, \
8 from scapy.layers.inet6 import IPv6, Ether, UDP
9 from scapy.utils6 import in6_mactoifaceid
10 from scapy.utils import inet_ntop, inet_pton
12 from framework import VppTestCase
13 from vpp_papi import VppEnum
17 def ip6_normalize(ip6):
18 return inet_ntop(AF_INET6, inet_pton(AF_INET6, ip6))
21 class TestDHCPv6DataPlane(VppTestCase):
22 """ DHCPv6 Data Plane Test Case """
26 super(TestDHCPv6DataPlane, cls).setUpClass()
29 def tearDownClass(cls):
30 super(TestDHCPv6DataPlane, cls).tearDownClass()
33 super(TestDHCPv6DataPlane, self).setUp()
35 self.create_pg_interfaces(range(1))
36 self.interfaces = list(self.pg_interfaces)
37 for i in self.interfaces:
41 self.server_duid = DUID_LL(lladdr=self.pg0.remote_mac)
44 for i in self.interfaces:
47 super(TestDHCPv6DataPlane, self).tearDown()
49 def test_dhcp_ia_na_send_solicit_receive_advertise(self):
50 """ Verify DHCPv6 IA NA Solicit packet and Advertise event """
52 self.vapi.dhcp6_clients_enable_disable()
54 self.pg_enable_capture(self.pg_interfaces)
56 address = {'address': '1:2:3::5',
59 self.vapi.dhcp6_send_client_message(
60 msg_type=VppEnum.vl_api_dhcpv6_msg_type_t.DHCPV6_MSG_API_SOLICIT,
61 sw_if_index=self.pg0.sw_if_index,
67 rx_list = self.pg0.get_capture(1)
68 self.assertEqual(len(rx_list), 1)
71 self.assertEqual(packet.haslayer(IPv6), 1)
72 self.assertEqual(packet[IPv6].haslayer(DHCP6_Solicit), 1)
74 client_duid = packet[DHCP6OptClientId].duid
75 trid = packet[DHCP6_Solicit].trid
77 dst = ip6_normalize(packet[IPv6].dst)
78 dst2 = ip6_normalize("ff02::1:2")
79 self.assert_equal(dst, dst2)
80 src = ip6_normalize(packet[IPv6].src)
81 src2 = ip6_normalize(self.pg0.local_ip6_ll)
82 self.assert_equal(src, src2)
83 ia_na = packet[DHCP6OptIA_NA]
84 self.assert_equal(ia_na.T1, 20)
85 self.assert_equal(ia_na.T2, 40)
86 self.assert_equal(len(ia_na.ianaopts), 1)
87 address = ia_na.ianaopts[0]
88 self.assert_equal(address.addr, '1:2:3::5')
89 self.assert_equal(address.preflft, 60)
90 self.assert_equal(address.validlft, 120)
92 self.vapi.want_dhcp6_reply_events()
95 ia_na_opts = DHCP6OptIAAddress(addr='7:8::2', preflft=60,
97 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
98 IPv6(src=util.mk_ll_addr(self.pg0.remote_mac),
99 dst=self.pg0.local_ip6_ll) /
100 UDP(sport=547, dport=546) /
101 DHCP6_Advertise(trid=trid) /
102 DHCP6OptServerId(duid=self.server_duid) /
103 DHCP6OptClientId(duid=client_duid) /
104 DHCP6OptPref(prefval=7) /
105 DHCP6OptStatusCode(statuscode=1) /
106 DHCP6OptIA_NA(iaid=1, T1=20, T2=40, ianaopts=ia_na_opts)
108 self.pg0.add_stream([p])
111 ev = self.vapi.wait_for_event(1, "dhcp6_reply_event")
113 self.assert_equal(ev.preference, 7)
114 self.assert_equal(ev.status_code, 1)
115 self.assert_equal(ev.T1, 20)
116 self.assert_equal(ev.T2, 40)
118 reported_address = ev.addresses[0]
119 address = ia_na_opts.getfieldval("addr")
120 self.assert_equal(str(reported_address.address), address)
121 self.assert_equal(reported_address.preferred_time,
122 ia_na_opts.getfieldval("preflft"))
123 self.assert_equal(reported_address.valid_time,
124 ia_na_opts.getfieldval("validlft"))
127 self.vapi.want_dhcp6_reply_events(enable_disable=0)
129 def test_dhcp_pd_send_solicit_receive_advertise(self):
130 """ Verify DHCPv6 PD Solicit packet and Advertise event """
132 self.vapi.dhcp6_clients_enable_disable()
134 self.pg_enable_capture(self.pg_interfaces)
137 prefix = {'prefix': {'address': '1:2:3::', 'len': 50},
138 'preferred_time': 60,
141 self.vapi.dhcp6_pd_send_client_message(
142 msg_type=VppEnum.vl_api_dhcpv6_msg_type_t.DHCPV6_MSG_API_SOLICIT,
143 sw_if_index=self.pg0.sw_if_index,
147 n_prefixes=len(prefixes))
148 rx_list = self.pg0.get_capture(1)
149 self.assertEqual(len(rx_list), 1)
152 self.assertEqual(packet.haslayer(IPv6), 1)
153 self.assertEqual(packet[IPv6].haslayer(DHCP6_Solicit), 1)
155 client_duid = packet[DHCP6OptClientId].duid
156 trid = packet[DHCP6_Solicit].trid
158 dst = ip6_normalize(packet[IPv6].dst)
159 dst2 = ip6_normalize("ff02::1:2")
160 self.assert_equal(dst, dst2)
161 src = ip6_normalize(packet[IPv6].src)
162 src2 = ip6_normalize(self.pg0.local_ip6_ll)
163 self.assert_equal(src, src2)
164 ia_pd = packet[DHCP6OptIA_PD]
165 self.assert_equal(ia_pd.T1, 20)
166 self.assert_equal(ia_pd.T2, 40)
167 self.assert_equal(len(ia_pd.iapdopt), 1)
168 prefix = ia_pd.iapdopt[0]
169 self.assert_equal(prefix.prefix, '1:2:3::')
170 self.assert_equal(prefix.plen, 50)
171 self.assert_equal(prefix.preflft, 60)
172 self.assert_equal(prefix.validlft, 120)
174 self.vapi.want_dhcp6_pd_reply_events()
177 ia_pd_opts = DHCP6OptIAPrefix(prefix='7:8::', plen=56, preflft=60,
179 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
180 IPv6(src=util.mk_ll_addr(self.pg0.remote_mac),
181 dst=self.pg0.local_ip6_ll) /
182 UDP(sport=547, dport=546) /
183 DHCP6_Advertise(trid=trid) /
184 DHCP6OptServerId(duid=self.server_duid) /
185 DHCP6OptClientId(duid=client_duid) /
186 DHCP6OptPref(prefval=7) /
187 DHCP6OptStatusCode(statuscode=1) /
188 DHCP6OptIA_PD(iaid=1, T1=20, T2=40, iapdopt=ia_pd_opts)
190 self.pg0.add_stream([p])
193 ev = self.vapi.wait_for_event(1, "dhcp6_pd_reply_event")
195 self.assert_equal(ev.preference, 7)
196 self.assert_equal(ev.status_code, 1)
197 self.assert_equal(ev.T1, 20)
198 self.assert_equal(ev.T2, 40)
200 reported_prefix = ev.prefixes[0]
201 prefix = ia_pd_opts.getfieldval("prefix")
203 str(reported_prefix.prefix).split('/')[0], prefix)
204 self.assert_equal(int(str(reported_prefix.prefix).split('/')[1]),
205 ia_pd_opts.getfieldval("plen"))
206 self.assert_equal(reported_prefix.preferred_time,
207 ia_pd_opts.getfieldval("preflft"))
208 self.assert_equal(reported_prefix.valid_time,
209 ia_pd_opts.getfieldval("validlft"))
212 self.vapi.want_dhcp6_pd_reply_events(enable_disable=0)
215 class TestDHCPv6IANAControlPlane(VppTestCase):
216 """ DHCPv6 IA NA Control Plane Test Case """
220 super(TestDHCPv6IANAControlPlane, cls).setUpClass()
223 def tearDownClass(cls):
224 super(TestDHCPv6IANAControlPlane, cls).tearDownClass()
227 super(TestDHCPv6IANAControlPlane, self).setUp()
229 self.create_pg_interfaces(range(1))
230 self.interfaces = list(self.pg_interfaces)
231 for i in self.interfaces:
234 self.server_duid = DUID_LL(lladdr=self.pg0.remote_mac)
235 self.client_duid = None
239 fib = self.vapi.ip_route_dump(0, True)
240 self.initial_addresses = set(self.get_interface_addresses(fib,
243 self.pg_enable_capture(self.pg_interfaces)
246 self.vapi.dhcp6_client_enable_disable(self.pg0.sw_if_index)
249 self.vapi.dhcp6_client_enable_disable(self.pg0.sw_if_index, enable=0)
251 for i in self.interfaces:
254 super(TestDHCPv6IANAControlPlane, self).tearDown()
257 def get_interface_addresses(fib, pg):
260 if entry.route.prefix.prefixlen == 128:
261 path = entry.route.paths[0]
262 if path.sw_if_index == pg.sw_if_index:
263 lst.append(str(entry.route.prefix.network_address))
266 def get_addresses(self):
267 fib = self.vapi.ip_route_dump(0, True)
268 addresses = set(self.get_interface_addresses(fib, self.pg0))
269 return addresses.difference(self.initial_addresses)
271 def validate_duid_ll(self, duid):
274 def validate_packet(self, packet, msg_type, is_resend=False):
276 self.assertEqual(packet.haslayer(msg_type), 1)
277 client_duid = packet[DHCP6OptClientId].duid
278 if self.client_duid is None:
279 self.client_duid = client_duid
280 self.validate_duid_ll(client_duid)
282 self.assertEqual(self.client_duid, client_duid)
283 if msg_type != DHCP6_Solicit and msg_type != DHCP6_Rebind:
284 server_duid = packet[DHCP6OptServerId].duid
285 self.assertEqual(server_duid, self.server_duid)
287 self.assertEqual(self.trid, packet[msg_type].trid)
289 self.trid = packet[msg_type].trid
292 self.assertEqual(ip.dst, 'ff02::1:2')
293 self.assertEqual(udp.sport, 546)
294 self.assertEqual(udp.dport, 547)
295 dhcpv6 = packet[msg_type]
296 elapsed_time = dhcpv6[DHCP6OptElapsedTime]
298 self.assertNotEqual(elapsed_time.elapsedtime, 0)
300 self.assertEqual(elapsed_time.elapsedtime, 0)
301 except BaseException:
305 def wait_for_packet(self, msg_type, timeout=None, is_resend=False):
308 rx_list = self.pg0.get_capture(1, timeout=timeout)
310 self.validate_packet(packet, msg_type, is_resend=is_resend)
312 def wait_for_solicit(self, timeout=None, is_resend=False):
313 self.wait_for_packet(DHCP6_Solicit, timeout, is_resend=is_resend)
315 def wait_for_request(self, timeout=None, is_resend=False):
316 self.wait_for_packet(DHCP6_Request, timeout, is_resend=is_resend)
318 def wait_for_renew(self, timeout=None, is_resend=False):
319 self.wait_for_packet(DHCP6_Renew, timeout, is_resend=is_resend)
321 def wait_for_rebind(self, timeout=None, is_resend=False):
322 self.wait_for_packet(DHCP6_Rebind, timeout, is_resend=is_resend)
324 def wait_for_release(self, timeout=None, is_resend=False):
325 self.wait_for_packet(DHCP6_Release, timeout, is_resend=is_resend)
327 def send_packet(self, msg_type, t1=None, t2=None, ianaopts=None):
333 opt_ia_na = DHCP6OptIA_NA(iaid=1, T1=t1, T2=t2)
335 opt_ia_na = DHCP6OptIA_NA(iaid=1, T1=t1, T2=t2, ianaopts=ianaopts)
336 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
337 IPv6(src=util.mk_ll_addr(self.pg0.remote_mac),
338 dst=self.pg0.local_ip6_ll) /
339 UDP(sport=547, dport=546) /
340 msg_type(trid=self.trid) /
341 DHCP6OptServerId(duid=self.server_duid) /
342 DHCP6OptClientId(duid=self.client_duid) /
345 self.pg0.add_stream([p])
346 self.pg_enable_capture(self.pg_interfaces)
349 def send_advertise(self, t1=None, t2=None, ianaopts=None):
350 self.send_packet(DHCP6_Advertise, t1, t2, ianaopts)
352 def send_reply(self, t1=None, t2=None, ianaopts=None):
353 self.send_packet(DHCP6_Reply, t1, t2, ianaopts)
355 def test_T1_and_T2_timeouts(self):
356 """ Test T1 and T2 timeouts """
358 self.wait_for_solicit()
359 self.send_advertise()
360 self.wait_for_request()
365 self.wait_for_renew()
367 self.pg_enable_capture(self.pg_interfaces)
371 self.wait_for_rebind()
373 def test_addresses(self):
374 """ Test handling of addresses """
376 ia_na_opts = DHCP6OptIAAddress(addr='7:8::2', preflft=1,
379 self.wait_for_solicit()
380 self.send_advertise(t1=20, t2=40, ianaopts=ia_na_opts)
381 self.wait_for_request()
382 self.send_reply(t1=20, t2=40, ianaopts=ia_na_opts)
385 # check FIB for new address
386 new_addresses = self.get_addresses()
387 self.assertEqual(len(new_addresses), 1)
388 addr = list(new_addresses)[0]
389 self.assertEqual(addr, '7:8::2')
393 # check that the address is deleted
394 fib = self.vapi.ip_route_dump(0, True)
395 addresses = set(self.get_interface_addresses(fib, self.pg0))
396 new_addresses = addresses.difference(self.initial_addresses)
397 self.assertEqual(len(new_addresses), 0)
399 def test_sending_client_messages_solicit(self):
400 """ VPP receives messages from DHCPv6 client """
402 self.wait_for_solicit()
403 self.send_packet(DHCP6_Solicit)
404 self.send_packet(DHCP6_Request)
405 self.send_packet(DHCP6_Renew)
406 self.send_packet(DHCP6_Rebind)
408 self.wait_for_solicit(is_resend=True)
410 def test_sending_inappropriate_packets(self):
411 """ Server sends messages with inappropriate message types """
413 self.wait_for_solicit()
415 self.wait_for_solicit(is_resend=True)
416 self.send_advertise()
417 self.wait_for_request()
418 self.send_advertise()
419 self.wait_for_request(is_resend=True)
421 self.wait_for_renew()
423 def test_no_address_available_in_advertise(self):
424 """ Advertise message contains NoAddrsAvail status code """
426 self.wait_for_solicit()
427 noavail = DHCP6OptStatusCode(statuscode=2) # NoAddrsAvail
428 self.send_advertise(ianaopts=noavail)
429 self.wait_for_solicit(is_resend=True)
431 def test_preferred_greater_than_valid_lifetime(self):
432 """ Preferred lifetime is greater than valid lifetime """
434 self.wait_for_solicit()
435 self.send_advertise()
436 self.wait_for_request()
437 ia_na_opts = DHCP6OptIAAddress(addr='7:8::2', preflft=4, validlft=3)
438 self.send_reply(ianaopts=ia_na_opts)
442 # check FIB contains no addresses
443 fib = self.vapi.ip_route_dump(0, True)
444 addresses = set(self.get_interface_addresses(fib, self.pg0))
445 new_addresses = addresses.difference(self.initial_addresses)
446 self.assertEqual(len(new_addresses), 0)
448 def test_T1_greater_than_T2(self):
449 """ T1 is greater than T2 """
451 self.wait_for_solicit()
452 self.send_advertise()
453 self.wait_for_request()
454 ia_na_opts = DHCP6OptIAAddress(addr='7:8::2', preflft=4, validlft=8)
455 self.send_reply(t1=80, t2=40, ianaopts=ia_na_opts)
459 # check FIB contains no addresses
460 fib = self.vapi.ip_route_dump(0, True)
461 addresses = set(self.get_interface_addresses(fib, self.pg0))
462 new_addresses = addresses.difference(self.initial_addresses)
463 self.assertEqual(len(new_addresses), 0)
466 class TestDHCPv6PDControlPlane(VppTestCase):
467 """ DHCPv6 PD Control Plane Test Case """
471 super(TestDHCPv6PDControlPlane, cls).setUpClass()
474 def tearDownClass(cls):
475 super(TestDHCPv6PDControlPlane, cls).tearDownClass()
478 super(TestDHCPv6PDControlPlane, self).setUp()
480 self.create_pg_interfaces(range(2))
481 self.interfaces = list(self.pg_interfaces)
482 for i in self.interfaces:
485 self.server_duid = DUID_LL(lladdr=self.pg0.remote_mac)
486 self.client_duid = None
490 fib = self.vapi.ip_route_dump(0, True)
491 self.initial_addresses = set(self.get_interface_addresses(fib,
494 self.pg_enable_capture(self.pg_interfaces)
497 self.prefix_group = 'my-pd-prefix-group'
499 self.vapi.dhcp6_pd_client_enable_disable(
500 self.pg0.sw_if_index,
501 prefix_group=self.prefix_group)
504 self.vapi.dhcp6_pd_client_enable_disable(self.pg0.sw_if_index,
507 for i in self.interfaces:
510 super(TestDHCPv6PDControlPlane, self).tearDown()
513 def get_interface_addresses(fib, pg):
516 if entry.route.prefix.prefixlen == 128:
517 path = entry.route.paths[0]
518 if path.sw_if_index == pg.sw_if_index:
519 lst.append(str(entry.route.prefix.network_address))
522 def get_addresses(self):
523 fib = self.vapi.ip_route_dump(0, True)
524 addresses = set(self.get_interface_addresses(fib, self.pg1))
525 return addresses.difference(self.initial_addresses)
527 def validate_duid_ll(self, duid):
530 def validate_packet(self, packet, msg_type, is_resend=False):
532 self.assertEqual(packet.haslayer(msg_type), 1)
533 client_duid = packet[DHCP6OptClientId].duid
534 if self.client_duid is None:
535 self.client_duid = client_duid
536 self.validate_duid_ll(client_duid)
538 self.assertEqual(self.client_duid, client_duid)
539 if msg_type != DHCP6_Solicit and msg_type != DHCP6_Rebind:
540 server_duid = packet[DHCP6OptServerId].duid
541 self.assertEqual(server_duid, self.server_duid)
543 self.assertEqual(self.trid, packet[msg_type].trid)
545 self.trid = packet[msg_type].trid
548 self.assertEqual(ip.dst, 'ff02::1:2')
549 self.assertEqual(udp.sport, 546)
550 self.assertEqual(udp.dport, 547)
551 dhcpv6 = packet[msg_type]
552 elapsed_time = dhcpv6[DHCP6OptElapsedTime]
554 self.assertNotEqual(elapsed_time.elapsedtime, 0)
556 self.assertEqual(elapsed_time.elapsedtime, 0)
557 except BaseException:
561 def wait_for_packet(self, msg_type, timeout=None, is_resend=False):
564 rx_list = self.pg0.get_capture(1, timeout=timeout)
566 self.validate_packet(packet, msg_type, is_resend=is_resend)
568 def wait_for_solicit(self, timeout=None, is_resend=False):
569 self.wait_for_packet(DHCP6_Solicit, timeout, is_resend=is_resend)
571 def wait_for_request(self, timeout=None, is_resend=False):
572 self.wait_for_packet(DHCP6_Request, timeout, is_resend=is_resend)
574 def wait_for_renew(self, timeout=None, is_resend=False):
575 self.wait_for_packet(DHCP6_Renew, timeout, is_resend=is_resend)
577 def wait_for_rebind(self, timeout=None, is_resend=False):
578 self.wait_for_packet(DHCP6_Rebind, timeout, is_resend=is_resend)
580 def wait_for_release(self, timeout=None, is_resend=False):
581 self.wait_for_packet(DHCP6_Release, timeout, is_resend=is_resend)
583 def send_packet(self, msg_type, t1=None, t2=None, iapdopt=None):
589 opt_ia_pd = DHCP6OptIA_PD(iaid=1, T1=t1, T2=t2)
591 opt_ia_pd = DHCP6OptIA_PD(iaid=1, T1=t1, T2=t2, iapdopt=iapdopt)
592 p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
593 IPv6(src=util.mk_ll_addr(self.pg0.remote_mac),
594 dst=self.pg0.local_ip6_ll) /
595 UDP(sport=547, dport=546) /
596 msg_type(trid=self.trid) /
597 DHCP6OptServerId(duid=self.server_duid) /
598 DHCP6OptClientId(duid=self.client_duid) /
601 self.pg0.add_stream([p])
602 self.pg_enable_capture(self.pg_interfaces)
605 def send_advertise(self, t1=None, t2=None, iapdopt=None):
606 self.send_packet(DHCP6_Advertise, t1, t2, iapdopt)
608 def send_reply(self, t1=None, t2=None, iapdopt=None):
609 self.send_packet(DHCP6_Reply, t1, t2, iapdopt)
611 def test_T1_and_T2_timeouts(self):
612 """ Test T1 and T2 timeouts """
614 self.wait_for_solicit()
615 self.send_advertise()
616 self.wait_for_request()
621 self.wait_for_renew()
623 self.pg_enable_capture(self.pg_interfaces)
627 self.wait_for_rebind()
629 def test_prefixes(self):
630 """ Test handling of prefixes """
635 address_bin_1 = '\x00' * 6 + '\x00\x02' + '\x00' * 6 + '\x04\x05'
636 address_prefix_length_1 = 60
637 self.vapi.ip6_add_del_address_using_prefix(self.pg1.sw_if_index,
639 address_prefix_length_1,
642 ia_pd_opts = DHCP6OptIAPrefix(prefix='7:8::', plen=56, preflft=2,
645 self.wait_for_solicit()
646 self.send_advertise(t1=20, t2=40, iapdopt=ia_pd_opts)
647 self.wait_for_request()
648 self.send_reply(t1=20, t2=40, iapdopt=ia_pd_opts)
651 # check FIB for new address
652 new_addresses = self.get_addresses()
653 self.assertEqual(len(new_addresses), 1)
654 addr = list(new_addresses)[0]
655 self.assertEqual(addr, '7:8:0:2::405')
659 address_bin_2 = '\x00' * 6 + '\x00\x76' + '\x00' * 6 + '\x04\x06'
660 address_prefix_length_2 = 62
661 self.vapi.ip6_add_del_address_using_prefix(self.pg1.sw_if_index,
663 address_prefix_length_2,
668 # check FIB contains 2 addresses
669 fib = self.vapi.ip_route_dump(0, True)
670 addresses = set(self.get_interface_addresses(fib, self.pg1))
671 new_addresses = addresses.difference(self.initial_addresses)
672 self.assertEqual(len(new_addresses), 2)
673 addr1 = list(new_addresses)[0]
674 addr2 = list(new_addresses)[1]
675 if addr1 == '7:8:0:76::406':
676 addr1, addr2 = addr2, addr1
677 self.assertEqual(addr1, '7:8:0:2::405')
678 self.assertEqual(addr2, '7:8:0:76::406')
682 # check that the addresses are deleted
683 fib = self.vapi.ip_route_dump(0, True)
684 addresses = set(self.get_interface_addresses(fib, self.pg1))
685 new_addresses = addresses.difference(self.initial_addresses)
686 self.assertEqual(len(new_addresses), 0)
689 if address_bin_1 is not None:
690 self.vapi.ip6_add_del_address_using_prefix(
691 self.pg1.sw_if_index, address_bin_1,
692 address_prefix_length_1, self.prefix_group, is_add=0)
693 if address_bin_2 is not None:
694 self.vapi.ip6_add_del_address_using_prefix(
695 self.pg1.sw_if_index, address_bin_2,
696 address_prefix_length_2, self.prefix_group, is_add=0)
698 def test_sending_client_messages_solicit(self):
699 """ VPP receives messages from DHCPv6 client """
701 self.wait_for_solicit()
702 self.send_packet(DHCP6_Solicit)
703 self.send_packet(DHCP6_Request)
704 self.send_packet(DHCP6_Renew)
705 self.send_packet(DHCP6_Rebind)
707 self.wait_for_solicit(is_resend=True)
709 def test_sending_inappropriate_packets(self):
710 """ Server sends messages with inappropriate message types """
712 self.wait_for_solicit()
714 self.wait_for_solicit(is_resend=True)
715 self.send_advertise()
716 self.wait_for_request()
717 self.send_advertise()
718 self.wait_for_request(is_resend=True)
720 self.wait_for_renew()
722 def test_no_prefix_available_in_advertise(self):
723 """ Advertise message contains NoPrefixAvail status code """
725 self.wait_for_solicit()
726 noavail = DHCP6OptStatusCode(statuscode=6) # NoPrefixAvail
727 self.send_advertise(iapdopt=noavail)
728 self.wait_for_solicit(is_resend=True)
730 def test_preferred_greater_than_valid_lifetime(self):
731 """ Preferred lifetime is greater than valid lifetime """
734 address_bin = '\x00' * 6 + '\x00\x02' + '\x00' * 6 + '\x04\x05'
735 address_prefix_length = 60
736 self.vapi.ip6_add_del_address_using_prefix(self.pg1.sw_if_index,
738 address_prefix_length,
741 self.wait_for_solicit()
742 self.send_advertise()
743 self.wait_for_request()
744 ia_pd_opts = DHCP6OptIAPrefix(prefix='7:8::', plen=56, preflft=4,
746 self.send_reply(iapdopt=ia_pd_opts)
750 # check FIB contains no addresses
751 fib = self.vapi.ip_route_dump(0, True)
752 addresses = set(self.get_interface_addresses(fib, self.pg1))
753 new_addresses = addresses.difference(self.initial_addresses)
754 self.assertEqual(len(new_addresses), 0)
757 self.vapi.ip6_add_del_address_using_prefix(self.pg1.sw_if_index,
759 address_prefix_length,
763 def test_T1_greater_than_T2(self):
764 """ T1 is greater than T2 """
767 address_bin = '\x00' * 6 + '\x00\x02' + '\x00' * 6 + '\x04\x05'
768 address_prefix_length = 60
769 self.vapi.ip6_add_del_address_using_prefix(self.pg1.sw_if_index,
771 address_prefix_length,
774 self.wait_for_solicit()
775 self.send_advertise()
776 self.wait_for_request()
777 ia_pd_opts = DHCP6OptIAPrefix(prefix='7:8::', plen=56, preflft=4,
779 self.send_reply(t1=80, t2=40, iapdopt=ia_pd_opts)
783 # check FIB contains no addresses
784 fib = self.vapi.ip_route_dump(0, True)
785 addresses = set(self.get_interface_addresses(fib, self.pg1))
786 new_addresses = addresses.difference(self.initial_addresses)
787 self.assertEqual(len(new_addresses), 0)
790 self.vapi.ip6_add_del_address_using_prefix(self.pg1.sw_if_index,
792 address_prefix_length,