From 174d53bf95c4cc7a78b4f94c43a1be15fdec2678 Mon Sep 17 00:00:00 2001 From: Prince Sunny Date: Wed, 6 Dec 2017 01:35:15 +0000 Subject: [PATCH 1/2] Implementation of directed broadcast Test --- .../test/files/ptftests/dir_bcast_test.py | 136 ++++++++++++++++++ ansible/roles/test/tasks/dir_bcast.yml | 42 ++++++ ansible/roles/test/tasks/sonic.yml | 4 + 3 files changed, 182 insertions(+) create mode 100644 ansible/roles/test/files/ptftests/dir_bcast_test.py create mode 100644 ansible/roles/test/tasks/dir_bcast.yml diff --git a/ansible/roles/test/files/ptftests/dir_bcast_test.py b/ansible/roles/test/files/ptftests/dir_bcast_test.py new file mode 100644 index 00000000000..2d019851656 --- /dev/null +++ b/ansible/roles/test/files/ptftests/dir_bcast_test.py @@ -0,0 +1,136 @@ +''' +Description: This file contains the Directed Broadcast test for SONIC + +Usage: Examples of how to use log analyzer + ptf --test-dir ptftests dir_bcast_test.BcastTest --platform remote -t "testbed_type='t0';router_mac='00:01:02:03:04:05';vlan_info='/root/vlan_info.txt'" --relax --debug info --log-file /tmp/dir_bcast_test.log --disable-vxlan --disable-geneve --disable-erspan --disable-mpls --disable-nvgre + +''' + +#--------------------------------------------------------------------- +# Global imports +#--------------------------------------------------------------------- +import logging +import random +import ptf +import ptf.packet as scapy +import ptf.dataplane as dataplane + +from ptf import config +from ptf.base_tests import BaseTest +from ptf.mask import Mask +from ptf.testutils import * +from ipaddress import ip_address, ip_network + +class BcastTest(BaseTest): + ''' + @summary: Overview of functionality + Test sends a directed broadcast packet on one of the non-VLAN RIF interface and destined to the + broadcast IP of the VLAN RIF. It expects the packet to be broadcasted to all the member port of + VLAN + + This class receives a text file containing the VLAN IP address/prefix and the member port list + + For the device configured with VLAN interface and member ports, + - IP/UDP frame, UDP port - DHCP server port, Dst Mac = Router MAC, Dst IP = Directed Broadcast IP + ''' + + #--------------------------------------------------------------------- + # Class variables + #--------------------------------------------------------------------- + BROADCAST_MAC = 'ff:ff:ff:ff:ff:ff' + DHCP_SERVER_PORT = 67 + + def __init__(self): + ''' + @summary: constructor + ''' + BaseTest.__init__(self) + self.test_params = test_params_get() + + #--------------------------------------------------------------------- + + def setUp(self): + self.dataplane = ptf.dataplane_instance + self.router_mac = self.test_params['router_mac'] + self.setUpVlan(self.test_params['vlan_info']) + if self.test_params['testbed_type'] == 't0': + self.src_ports = range(1, 25) + range(28, 32) + if self.test_params['testbed_type'] == 't0-64': + self.src_ports = range(0, 2) + range(4, 18) + range(20, 33) + range(36, 43) + range(48, 49) + range(52, 59) + + #--------------------------------------------------------------------- + + def setUpVlan(self, file_path): + ''' + @summary: Populate the VLAN dictionary with IP/Prefix and member port list + ''' + self._vlan_dict = {} + with open(file_path, 'r') as f: + for line in f.readlines(): + entry = line.split(' ', 1) + prefix = ip_network(unicode(entry[0])) + self._vlan_dict[prefix] = [int(i) for i in entry[1].split()] + + #--------------------------------------------------------------------- + + def check_all_dir_bcast(self): + ''' + @summary: Loop through all the VLANs and send directed broadcast packets + ''' + for vlan_pfx in self._vlan_dict: + bcast_ip = str(ip_network(vlan_pfx).broadcast_address) + dst_port_list = self._vlan_dict[vlan_pfx] + self.check_ip_dir_bcast(bcast_ip, dst_port_list) + + #--------------------------------------------------------------------- + + def check_ip_dir_bcast(self, dst_bcast_ip, dst_port_list): + ''' + @summary: Check unicast IP forwarding and receiving on all member ports. + ''' + ip_src = "10.0.0.100" # Some src_ip + ip_dst = dst_bcast_ip + src_mac = self.dataplane.get_mac(0, 0) + bcast_mac = self.BROADCAST_MAC + udp_port = self.DHCP_SERVER_PORT + + pkt = simple_udp_packet(eth_dst=self.router_mac, + eth_src=src_mac, + ip_src=ip_src, + ip_dst=ip_dst, + udp_sport=udp_port, + udp_dport=udp_port) + + exp_pkt = simple_udp_packet(eth_dst=bcast_mac, + eth_src=self.router_mac, + ip_src=ip_src, + ip_dst=ip_dst, + udp_sport=udp_port, + udp_dport=udp_port) + + masked_exp_pkt = Mask(exp_pkt) + masked_exp_pkt.set_do_not_care_scapy(scapy.IP, "chksum") + masked_exp_pkt.set_do_not_care_scapy(scapy.IP, "ttl") + + src_port = random.choice([port for port in self.src_ports if port not in dst_port_list]) + send_packet(self, src_port, pkt) + logging.info("Sending packet from port " + str(src_port) + " to " + ip_dst) + + pkt_count = count_matched_packets_all_ports(self, masked_exp_pkt, dst_port_list) + ''' + Check if broadcast packet is received on all member ports of vlan + ''' + assert (pkt_count == len(dst_port_list)) + logging.info("Received " + str(pkt_count) + " broadcast packets ") + + return + + #--------------------------------------------------------------------- + + def runTest(self): + """ + @summary: Send Broadcast IP packet destined to a VLAN RIF and with unicast Dst MAC + Expect the packet to be received on all member ports of VLAN + """ + self.check_all_dir_bcast() + diff --git a/ansible/roles/test/tasks/dir_bcast.yml b/ansible/roles/test/tasks/dir_bcast.yml new file mode 100644 index 00000000000..455271b3bc8 --- /dev/null +++ b/ansible/roles/test/tasks/dir_bcast.yml @@ -0,0 +1,42 @@ +#----------------------------------------- +# Run dir_bcast test and Perform log analysis. +#----------------------------------------- + +# Pre-check testbed_type value +- fail: msg="testbed_type is not defined." + when: testbed_type is not defined + +- fail: msg="testbed_type {{testbed_type}} is invalid." + when: testbed_type not in ['t0', 't0-64'] + +- include_vars: "vars/topo_{{testbed_type}}.yml" + +- name: Expand properties into props + set_fact: props="{{configuration_properties['common']}}" + +- name: Gathering minigraph facts about the device + minigraph_facts: host={{ inventory_hostname }} + connection: local + +- debug : msg="Start dir_bcast Test" + +- name: Copy the test to ptf container + copy: src=roles/test/files/ptftests dest=/root + delegate_to: "{{ ptf_host }}" + +- name: Copy Vlan information file to PTF + template: src=roles/test/templates/fdb.j2 dest=/root/vlan_info.txt + delegate_to: "{{ ptf_host }}" + +- name: "Start PTF runner" + include: ptf_runner.yml + vars: + ptf_test_name: dir_bcast test + ptf_test_dir: ptftests + ptf_test_path: dir_bcast_test.BcastTest + ptf_platform: remote + ptf_test_params: + - testbed_type='{{testbed_type}}' + - router_mac='{{ansible_Ethernet0['macaddress']}}' + - vlan_info='/root/vlan_info.txt' + ptf_extra_options: "--relax --debug info --log-file /tmp/dir_bcast.BcastTest.{{ansible_date_time.iso8601}}.log" diff --git a/ansible/roles/test/tasks/sonic.yml b/ansible/roles/test/tasks/sonic.yml index d254ed6dbe2..097b692a061 100644 --- a/ansible/roles/test/tasks/sonic.yml +++ b/ansible/roles/test/tasks/sonic.yml @@ -116,6 +116,10 @@ include: mtu.yml tags: mtu +- name: Directed Broadcast test + include: dir_bcast.yml + tags: dir_bcast + ### When calling this FDB test, please add command line of what testbed_type and which PTF docker to test agains ### -e "testbed_type=t0 ptf_host=10.64.246.22" - name: FDB test From b11f800ad0486e7cb20bcd6d71c4ad0b21e1bead Mon Sep 17 00:00:00 2001 From: Prince Sunny Date: Thu, 7 Dec 2017 21:42:12 +0000 Subject: [PATCH 2/2] Addressed review comments --- ansible/roles/test/tasks/dir_bcast.yml | 6 +++--- ansible/roles/test/tasks/sonic.yml | 4 +--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/ansible/roles/test/tasks/dir_bcast.yml b/ansible/roles/test/tasks/dir_bcast.yml index 455271b3bc8..93496693ec1 100644 --- a/ansible/roles/test/tasks/dir_bcast.yml +++ b/ansible/roles/test/tasks/dir_bcast.yml @@ -15,18 +15,18 @@ set_fact: props="{{configuration_properties['common']}}" - name: Gathering minigraph facts about the device - minigraph_facts: host={{ inventory_hostname }} + minigraph_facts: host={{inventory_hostname}} connection: local - debug : msg="Start dir_bcast Test" - name: Copy the test to ptf container copy: src=roles/test/files/ptftests dest=/root - delegate_to: "{{ ptf_host }}" + delegate_to: "{{ptf_host}}" - name: Copy Vlan information file to PTF template: src=roles/test/templates/fdb.j2 dest=/root/vlan_info.txt - delegate_to: "{{ ptf_host }}" + delegate_to: "{{ptf_host}}" - name: "Start PTF runner" include: ptf_runner.yml diff --git a/ansible/roles/test/tasks/sonic.yml b/ansible/roles/test/tasks/sonic.yml index 097b692a061..56cf17b7536 100644 --- a/ansible/roles/test/tasks/sonic.yml +++ b/ansible/roles/test/tasks/sonic.yml @@ -106,7 +106,7 @@ include: reboot.yml tags: reboot -### When calling this FIB test, please add command line of what testbed_type and which PTF docker to test against +### When calling the following tests, please add command line of what testbed_type and which PTF docker to test against ### -e "testbed_type=t1-lag ptf_host=10.0.0.200" - name: Fib test include: fib.yml @@ -120,8 +120,6 @@ include: dir_bcast.yml tags: dir_bcast -### When calling this FDB test, please add command line of what testbed_type and which PTF docker to test agains -### -e "testbed_type=t0 ptf_host=10.64.246.22" - name: FDB test include: fdb.yml tags: fdb