-
Notifications
You must be signed in to change notification settings - Fork 1k
Added tests to verify MAX MTU packet handling #280
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,148 @@ | ||
| ''' | ||
| Description: This file contains the MTU test for SONIC | ||
|
|
||
| Usage: Examples of how to use log analyzer | ||
| ptf --test-dir ptftests mtu_test.MtuTest --platform remote -t "testbed_type='t1-lag';" --relax --debug info --log-file /tmp/mtu_test.log --disable-vxlan --disable-geneve --disable-erspan --disable-mpls --disable-nvgre --socket-recv-size 16384 | ||
|
|
||
| ''' | ||
|
|
||
| #--------------------------------------------------------------------- | ||
| # Global imports | ||
| #--------------------------------------------------------------------- | ||
| import logging | ||
| 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 * | ||
|
|
||
|
|
||
| class MtuTest(BaseTest): | ||
| ''' | ||
| @summary: Overview of functionality | ||
| Test sends a jumbo ICMP echo frame with MAX MTU size and expects the reply | ||
| back. It also sends a jumbo frame to a route destination for verifying the | ||
| forwarding functionality | ||
|
|
||
| For the device configured with IP-MTU=9100, PHY-MTU=9122, | ||
| - ICMP frame, the packet-len is 9114 (Subtracting 8 bytes of ICMP header from 9122) | ||
| - IP frame, the packet-len is 9122 (This includes the Layer 2 Ethernet header + FCS) | ||
| ''' | ||
|
|
||
| #--------------------------------------------------------------------- | ||
| # Class variables | ||
| #--------------------------------------------------------------------- | ||
| DEFAULT_PACKET_LEN = 9122 | ||
| ICMP_HDR_LEN = 8 | ||
|
|
||
| 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'] | ||
|
|
||
| #--------------------------------------------------------------------- | ||
|
|
||
| def check_icmp_mtu(self): | ||
| ''' | ||
| @summary: Check ICMP/Ping to DUT works for MAX MTU. | ||
| ''' | ||
| ip_src = "10.0.0.1" | ||
| ip_dst = "10.0.0.0" | ||
| src_mac = self.dataplane.get_mac(0, 0) | ||
|
|
||
| pktlen = (self.DEFAULT_PACKET_LEN - self.ICMP_HDR_LEN) | ||
|
|
||
| pkt = simple_icmp_packet(pktlen=pktlen, | ||
| eth_dst=self.router_mac, | ||
| eth_src=src_mac, | ||
| ip_src=ip_src, | ||
| ip_dst=ip_dst, | ||
| ip_ttl=64) | ||
|
|
||
| exp_pkt = simple_icmp_packet(pktlen=pktlen, | ||
| eth_src=self.router_mac, | ||
| ip_src=ip_dst, | ||
| ip_dst=ip_src, | ||
| icmp_type=0) | ||
|
|
||
| masked_exp_pkt = Mask(exp_pkt) | ||
| masked_exp_pkt.set_do_not_care_scapy(scapy.Ether, "dst") | ||
| masked_exp_pkt.set_do_not_care_scapy(scapy.IP, "id") | ||
| masked_exp_pkt.set_do_not_care_scapy(scapy.IP, "chksum") | ||
| masked_exp_pkt.set_do_not_care_scapy(scapy.IP, "ttl") | ||
| masked_exp_pkt.set_do_not_care_scapy(scapy.ICMP, "chksum") | ||
|
|
||
| src_port = 0 | ||
| send_packet(self, src_port, pkt) | ||
| logging.info("Sending packet from port " + str(src_port) + " to " + ip_dst) | ||
| dst_port_list = [0,1] | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why are there two ports in the list? the icmp reply packet should arrive from the src_port as well. It should not be received at other ports.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In t1-lag topology, 0 and 1 are part of PortChannel0. The reply packet can be received on either port. In t1 topology, the ICMP reply will be received on 0 |
||
|
|
||
| (matched_index, received) = verify_packet_any_port(self, masked_exp_pkt, dst_port_list) | ||
|
|
||
| assert received | ||
|
|
||
| matched_port = dst_port_list[matched_index] | ||
| logging.info("Received packet at " + str(matched_port)) | ||
|
|
||
| return | ||
|
|
||
| #--------------------------------------------------------------------- | ||
|
|
||
| def check_ip_mtu(self): | ||
| ''' | ||
| @summary: Check unicast IP forwarding in DUT works for MAX MTU. | ||
| ''' | ||
| ip_src = "10.0.0.1" | ||
| ip_dst = "10.0.0.63" | ||
| src_mac = self.dataplane.get_mac(0, 0) | ||
|
|
||
| pkt = simple_ip_packet(pktlen=self.DEFAULT_PACKET_LEN, | ||
| eth_dst=self.router_mac, | ||
| eth_src=src_mac, | ||
| ip_src=ip_src, | ||
| ip_dst=ip_dst, | ||
| ip_ttl=64) | ||
|
|
||
| exp_pkt = simple_ip_packet(pktlen=self.DEFAULT_PACKET_LEN, | ||
| eth_src=self.router_mac, | ||
| ip_src=ip_src, | ||
| ip_dst=ip_dst, | ||
| ip_ttl=63) | ||
|
|
||
| masked_exp_pkt = Mask(exp_pkt) | ||
| masked_exp_pkt.set_do_not_care_scapy(scapy.Ether, "dst") | ||
|
|
||
| src_port = 0 | ||
| send_packet(self, src_port, pkt) | ||
| logging.info("Sending packet from port " + str(src_port) + " to " + ip_dst) | ||
| dst_port_list = [31] | ||
|
|
||
| (matched_index, received) = verify_packet_any_port(self, masked_exp_pkt, dst_port_list) | ||
|
|
||
| assert received | ||
|
|
||
| matched_port = dst_port_list[matched_index] | ||
| logging.info("Received packet at " + str(matched_port)) | ||
|
|
||
| return | ||
|
|
||
| #--------------------------------------------------------------------- | ||
|
|
||
| def runTest(self): | ||
| """ | ||
| @summary: Send packet(Max MTU) to test on Ping request/response and unicast IP destination. | ||
| Expect the packet to be received from one of the expected ports | ||
| """ | ||
| self.check_icmp_mtu() | ||
| self.check_ip_mtu() | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,42 @@ | ||
| #----------------------------------------- | ||
| # Run MTU 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 ['t1-lag', 't1'] | ||
|
|
||
| - include_vars: "vars/topo_{{testbed_type}}.yml" | ||
|
|
||
| - name: Expand properties into props | ||
| set_fact: props="{{configuration_properties['spine']}}" | ||
| when: testbed_type in ['t1', 't1-lag'] | ||
|
|
||
| - name: Expand ToR properties into props | ||
| set_fact: props_tor="{{configuration_properties['tor']}}" | ||
| when: testbed_type in ['t1', 't1-lag'] | ||
|
|
||
| - name: Gathering minigraph facts about the device | ||
| minigraph_facts: host={{ inventory_hostname }} | ||
| connection: local | ||
|
|
||
| - debug : msg="Start MTU Test" | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can we first get the mtu Ethernet0 on the DUT use the mtu as a parameter to send the packet. Then, it makes our test more generic? You can get the mtu via ansible_facts, check below. https://stackoverflow.com/questions/18839509/where-can-i-get-a-list-of-ansible-pre-defined-variables
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This shall be addressed in the next phase commit |
||
|
|
||
| - name: copy the test to ptf container | ||
| copy: src=roles/test/files/ptftests dest=/root | ||
| delegate_to: "{{ ptf_host }}" | ||
|
|
||
| - name: "Start PTF runner" | ||
| include: ptf_runner.yml | ||
| vars: | ||
| ptf_test_name: MTU test | ||
| ptf_test_dir: ptftests | ||
| ptf_test_path: mtu_test.MtuTest | ||
| ptf_platform: remote | ||
| ptf_test_params: | ||
| - testbed_type='{{testbed_type}}' | ||
| - router_mac='{{ansible_Ethernet0['macaddress']}}' | ||
| ptf_extra_options: "--relax --debug info --log-file /tmp/mtu_test.MtuTest.{{ansible_date_time.iso8601}}.log --socket-recv-size 16384" | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should we set the DF bit in the packet to make sure we are not fragment the packet anywhere and we were not really testing the MTU sized packet?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see a param in the API to set the DF bit. Will discuss with you!