From 5f2d8fcca28a7d2c75578f09a77a3eb3ec935497 Mon Sep 17 00:00:00 2001 From: Jing Ma Date: Fri, 27 Nov 2020 00:32:51 +0800 Subject: [PATCH] [thread-cert] refactor case 5.3.7 using pktverify (#5815) --- .../Cert_5_3_07_DuplicateAddress.py | 161 +++++++++++++----- 1 file changed, 122 insertions(+), 39 deletions(-) diff --git a/tests/scripts/thread-cert/Cert_5_3_07_DuplicateAddress.py b/tests/scripts/thread-cert/Cert_5_3_07_DuplicateAddress.py index 3abb1e40d..c4df00f9a 100755 --- a/tests/scripts/thread-cert/Cert_5_3_07_DuplicateAddress.py +++ b/tests/scripts/thread-cert/Cert_5_3_07_DuplicateAddress.py @@ -31,51 +31,81 @@ import unittest import command import config +import copy import mle import thread_cert +from pktverify.consts import WIRESHARK_OVERRIDE_PREFS, ADDR_ERR_URI, ADDR_QRY_URI, ADDR_NTF_URI, MLE_CHILD_ID_REQUEST, MLE_CHILD_ID_RESPONSE, REALM_LOCAL_ALL_ROUTERS_ADDRESS, NL_TARGET_EID_TLV, NL_RLOC16_TLV, NL_ML_EID_TLV +from pktverify.packet_verifier import PacketVerifier DUT_LEADER = 1 ROUTER1 = 2 ROUTER2 = 3 MED1 = 4 SED1 = 5 -MED3 = 6 +MED2 = 6 -MTDS = [MED1, SED1, MED3] +MTDS = [MED1, SED1, MED2] +ON_MESH_PREFIX = '2001::/64' +IPV6_ADDR = '2001::1234' + +# Test Purpose and Description: +# ----------------------------- +# The purpose of this test case is to validate the DUT’s ability to perform +# duplicate address detection. +# +# Test Topology: +# ------------- +# MED_2 - Leader(DUT) +# / \ +# Router_1 Router_2 +# | | +# MED_1 SED +# +# DUT Types: +# ---------- +# Leader class Cert_5_3_7_DuplicateAddress(thread_cert.TestCase): + USE_MESSAGE_FACTORY = False + TOPOLOGY = { DUT_LEADER: { + 'name': 'LEADER', 'mode': 'rdn', 'panid': 0xface, - 'allowlist': [ROUTER1, ROUTER2, MED3] + 'allowlist': [ROUTER1, ROUTER2, MED2] }, ROUTER1: { + 'name': 'ROUTER_1', 'mode': 'rdn', 'panid': 0xface, 'router_selection_jitter': 1, 'allowlist': [DUT_LEADER, MED1] }, ROUTER2: { + 'name': 'ROUTER_2', 'mode': 'rdn', 'panid': 0xface, 'router_selection_jitter': 1, 'allowlist': [DUT_LEADER, SED1] }, MED1: { + 'name': 'MED_1', 'is_mtd': True, 'mode': 'rn', 'panid': 0xface, 'allowlist': [ROUTER1] }, SED1: { + 'name': 'SED', 'is_mtd': True, 'mode': '-', 'panid': 0xface, 'allowlist': [ROUTER2] }, - MED3: { + MED2: { + 'name': 'MED_2', 'is_mtd': True, 'mode': 'rn', 'panid': 0xface, @@ -83,16 +113,18 @@ class Cert_5_3_7_DuplicateAddress(thread_cert.TestCase): }, } + # override wireshark preferences with case needed parameters + CASE_WIRESHARK_PREFS = copy.deepcopy(WIRESHARK_OVERRIDE_PREFS) + CASE_WIRESHARK_PREFS['6lowpan.context1'] = ON_MESH_PREFIX + def test(self): - # 1 self.nodes[DUT_LEADER].start() self.simulator.go(5) self.assertEqual(self.nodes[DUT_LEADER].get_state(), 'leader') - for i in range(ROUTER1, MED3 + 1): + for i in range(ROUTER1, MED2 + 1): self.nodes[i].start() - - self.simulator.go(5) + self.simulator.go(5) for i in [ROUTER1, ROUTER2]: self.assertEqual(self.nodes[i].get_state(), 'router') @@ -100,43 +132,94 @@ class Cert_5_3_7_DuplicateAddress(thread_cert.TestCase): for i in MTDS: self.assertEqual(self.nodes[i].get_state(), 'child') - # 2 - leader_messages = self.simulator.get_messages_sent_by(DUT_LEADER) - msg = leader_messages.next_mle_message(mle.CommandType.ADVERTISEMENT) - command.check_mle_advertisement(msg) + self.collect_ipaddrs() + self.collect_rlocs() - # 3 - self.nodes[ROUTER2].add_prefix('2001:2:0:1::/64', 'paros') + self.nodes[ROUTER2].add_prefix(ON_MESH_PREFIX, 'paros') self.nodes[ROUTER2].register_netdata() - # Set lowpan context of sniffer - self.simulator.set_lowpan_context(1, '2001:2:0:1::/64') - - self.nodes[MED1].add_ipaddr('2001:2:0:1::1234') - self.nodes[SED1].add_ipaddr('2001:2:0:1::1234') - + self.nodes[MED1].add_ipaddr(IPV6_ADDR) + self.nodes[SED1].add_ipaddr(IPV6_ADDR) self.simulator.go(5) - # 4 - # Flush the message queue to avoid possible impact on follow-up - # verification. - self.simulator.get_messages_sent_by(DUT_LEADER) - - self.nodes[MED3].ping('2001:2:0:1::1234') - - # Verify DUT_LEADER sent an Address Query Request to the Realm local - # address. - dut_messages = self.simulator.get_messages_sent_by(DUT_LEADER) - msg = dut_messages.next_coap_message('0.02', '/a/aq') - command.check_address_query(msg, self.nodes[DUT_LEADER], config.REALM_LOCAL_ALL_ROUTERS_ADDRESS) - - # 5 & 6 - # Verify DUT_LEADER sent an Address Error Notification to the Realm - # local address. + self.nodes[MED2].ping(IPV6_ADDR) self.simulator.go(5) - dut_messages = self.simulator.get_messages_sent_by(DUT_LEADER) - msg = dut_messages.next_coap_message('0.02', '/a/ae') - command.check_address_error_notification(msg, self.nodes[DUT_LEADER], config.REALM_LOCAL_ALL_ROUTERS_ADDRESS) + + def verify(self, pv): + pkts = pv.pkts + pv.summary.show() + + LEADER = pv.vars['LEADER'] + LEADER_RLOC = pv.vars['LEADER_RLOC'] + ROUTER_1 = pv.vars['ROUTER_1'] + ROUTER_2 = pv.vars['ROUTER_2'] + MED_1 = pv.vars['MED_1'] + MED_2 = pv.vars['MED_2'] + SED = pv.vars['SED'] + MM = pv.vars['MM_PORT'] + + # Step 1: Ensure topology is formed correctly + for i in (1, 2): + pv.verify_attached('ROUTER_%d' % i, 'LEADER') + pv.verify_attached('MED_1', 'ROUTER_1', 'MTD') + pv.verify_attached('SED', 'ROUTER_2', 'MTD') + pv.verify_attached('MED_2', 'LEADER', 'MTD') + + # Step 5: MED_2 sends ICMPv6 Echo Request to address configured on MED_1 + # and SED_1 with Prefix 2001:: + # The DUT MUST multicast an Address Query message to the Realm-Local + # All Routers address (FF03::2): + # CoAP URI-Path + # - NON POST coap:// + # CoAP Payload + # - Target EID TLV + + pkts.filter_ping_request().\ + filter_wpan_src64(MED_2). \ + filter_ipv6_dst(IPV6_ADDR). \ + must_next() + pkts.filter_wpan_src64(LEADER).\ + filter_RLARMA().\ + filter_coap_request(ADDR_QRY_URI, port=MM).\ + filter(lambda p: p.thread_address.tlv.target_eid == IPV6_ADDR).\ + must_next() + + # Step 6: Router_1 & Router_2 respond with Address Notification message + # with matching Target TLVs + + for i in (1, 2): + with pkts.save_index(): + pkts.filter_wpan_src64(pv.vars['ROUTER_%d' %i]).\ + filter_ipv6_dst(LEADER_RLOC).\ + filter_coap_request(ADDR_NTF_URI, port=MM).\ + filter(lambda p: { + NL_ML_EID_TLV, + NL_RLOC16_TLV, + NL_TARGET_EID_TLV + } <= set(p.coap.tlv.type) and\ + p.thread_address.tlv.target_eid == IPV6_ADDR + ).\ + must_next() + + # Step 7: The DUT MUST multicast an Address Error Notification to the Realm-Local + # All Routers address (FF03::2): + # CoAP URI-Path + # - NON POST coap://[]:MM/a/ae + # CoAP Payload + # - Target EID TLV + # - ML-EID TLV + # + # The IPv6 Source address MUST be the RLOC of the originator + + pkts.filter_ipv6_src_dst(LEADER_RLOC, REALM_LOCAL_ALL_ROUTERS_ADDRESS).\ + filter_coap_request(ADDR_ERR_URI, port=MM).\ + filter(lambda p: { + NL_ML_EID_TLV, + NL_TARGET_EID_TLV + } == set(p.coap.tlv.type) and\ + p.thread_address.tlv.target_eid == IPV6_ADDR + ).\ + must_next() if __name__ == '__main__':