Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
149 changes: 149 additions & 0 deletions ansible/roles/test/files/acstests/everflow_policer_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
'''
Description: This file contains the EVERFLOW policer test

Usage: Examples of how to use:
ptf --test-dir acstests everflow_policer_test.EverflowPolicerTest --platform remote -t 'router_mac="00:02:03:04:05:00";src_port="20";dst_ports="21,22";verbose=True' --relax
'''


import ptf
import ptf.packet as scapy
import ptf.dataplane as dataplane
import ptf.testutils as testutils
from ptf.base_tests import BaseTest
from ptf.mask import Mask

class EverflowPolicerTest(BaseTest):

GRE_PROTOCOL_NUMBER = 47
NUM_OF_TOTAL_PACKETS = 200


def __init__(self):
'''
@summary: constructor
'''
BaseTest.__init__(self)
self.test_params = testutils.test_params_get()


def greFilter(self, pkt_str):
'''
@summaty: Filter GRE packets
'''
try:
pkt = scapy.Ether(pkt_str)

if scapy.IP not in pkt:
return False

return pkt[scapy.IP].proto == self.GRE_PROTOCOL_NUMBER
except:
return False


def setUp(self):
'''
@summary: Setup the test
'''
print ""

self.dataplane = ptf.dataplane_instance
self.hwsku = self.test_params['hwsku']
self.asic_type = self.test_params['asic_type']
self.router_mac = self.test_params['router_mac']
self.session_src_ip = "1.1.1.1"
self.session_dst_ip = "2.2.2.2"
self.session_ttl = 1
self.session_dscp = 8
self.src_port = int(self.test_params['src_port'])
self.dst_mirror_ports = [int(p) for p in self.test_params['dst_mirror_ports'].split(",") if p]
self.dst_ports = [int(p) for p in self.test_params['dst_ports'].split(",")]

self.base_pkt = testutils.simple_tcp_packet(
eth_dst = self.router_mac,
eth_src = self.dataplane.get_mac(0, 0),
ip_src = "20.0.0.1",
ip_dst = "30.0.0.1",
tcp_sport = 0x1234,
tcp_dport = 0x50,
ip_dscp = 9,
ip_ttl = 64)

def checkOriginalFlow(self):
"""
@summary: Send traffic & check how many original packets are received
@return: count: number of original packets received
"""
exp_pkt = self.base_pkt.copy()
exp_pkt['Ethernet'].src = self.router_mac
exp_pkt['IP'].ttl = self.base_pkt['IP'].ttl - 1

masked_exp_pkt = Mask(exp_pkt)
masked_exp_pkt.set_do_not_care_scapy(scapy.Ether, "dst")

self.dataplane.flush()

count = 0
for i in range(0, self.NUM_OF_TOTAL_PACKETS):
testutils.send_packet(self, self.src_port, self.base_pkt)
(rcv_device, rcv_port, rcv_pkt, pkt_time) = testutils.dp_poll(self, timeout=0.1, exp_pkt=masked_exp_pkt)
if rcv_pkt is not None:
count += 1
elif count == 0:
print "The first original packet is not recieved"
assert False # Fast failure without waiting for full iteration
print "Recieved " + str(count) + " original packets"
return count

def checkMirroredFlow(self):
"""
@summary: Send traffic & check how many mirrored packets are received
@return: count: number of mirrored packets received
"""
exp_pkt = testutils.simple_gre_packet(
eth_src = self.router_mac,
ip_src = self.session_src_ip,
ip_dst = self.session_dst_ip,
ip_dscp = self.session_dscp,
ip_id = 0,
#ip_flags = 0x10, # need to upgrade ptf version to support it
ip_ttl = self.session_ttl,
inner_frame = self.base_pkt)

exp_pkt['GRE'].proto = 0x88be

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, "flags")
masked_exp_pkt.set_do_not_care_scapy(scapy.IP, "chksum")

self.dataplane.flush()

count = 0
for i in range(0,self.NUM_OF_TOTAL_PACKETS):
testutils.send_packet(self, self.src_port, self.base_pkt)
(rcv_device, rcv_port, rcv_pkt, pkt_time) = testutils.dp_poll(self, timeout=0.1, exp_pkt=masked_exp_pkt)
if rcv_pkt is not None:
count += 1
elif count == 0:
print "The first mirrored packet is not recieved"
assert False # Fast failure without waiting for full iteration
print "Received " + str(count) + " mirrored packets after rate limiting"
return count


def runTest(self):
"""
@summary: Run EVERFLOW Policer Test
"""

# Send traffic and verify the original traffic is not rate limited
count = self.checkOriginalFlow()
assert count == self.NUM_OF_TOTAL_PACKETS

testutils.add_filter(self.greFilter)

# Send traffic and verify the mirroed traffic is rate limited
count = self.checkMirroredFlow()
assert count > 100 and count < self.NUM_OF_TOTAL_PACKETS # cbs = cir = 100
10 changes: 8 additions & 2 deletions ansible/roles/test/tasks/everflow_testbed/get_port_info.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
set_fact:
tor_ports: []
spine_ports: []
spine_ptf_ports: []
dst_port_1_is_lag_member: ""
dst_port_1_ptf_id: ""
dst_port_2: ""
Expand All @@ -21,7 +22,7 @@
when: "'T0' in item.value.name"

- name: Print tor ports
debug: msg="{{ tor_ports }}"
debug: msg={{ tor_ports }}

- name: Get spine ports
set_fact:
Expand All @@ -30,7 +31,12 @@
when: "'T2' in item.value.name"

- name: Print spine ports
debug: msg="{{ spine_ports }}"
debug: msg={{ spine_ports }}

- name: Define spine PTF ports
set_fact:
spine_ptf_ports: "{{ spine_ptf_ports + [minigraph_port_indices[item] | string] }}"
with_items: "{{ spine_ports }}"

- name: Define SRC port variables.
set_fact:
Expand Down
3 changes: 3 additions & 0 deletions ansible/roles/test/tasks/everflow_testbed/run_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@
- name: Run testcase 7 - ECMP route change (remove next hop used by session).
include: roles/test/tasks/everflow_testbed/testcase_7.yml

- name: Run testcase 8 - Policer enforced with DSCP value/mask
include: roles/test/tasks/everflow_testbed/testcase_8.yml

always:
- name: Remove route to unresolved next hop.
shell: vtysh -e "conf t" -e "no ip route {{ unresolved_nexthop_prefix }} {{ dst_port_2 }}"
Expand Down
76 changes: 76 additions & 0 deletions ansible/roles/test/tasks/everflow_testbed/testcase_8.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# Test case 8 - Policer enforced DSCP value/mask test

- set_fact:
policer_name: TEST_POLICER
policer_session_name: TEST_POLICER_SESSION
dscp_table_name: EVERFLOW_DSCP

- name: Create route with next hop {{ dst_port_1 }}.
shell: vtysh -e "conf t" -e "ip route {{ session_prefix_1 }} {{ neighbor_info_1['addr'] }}"
become: yes

- block:
- name: Create a policer
shell: |
redis-cli -n 4 hmset "POLICER|{{policer_name}}" "meter_type" "packets" "mode" "sr_tcm" "cir" "100" "cbs" "100" "red_packet_action" "drop"
become: yes

- name: Create a policer enforced mirror session
shell: |
config mirror_session add {{policer_session_name}} {{session_src_ip}} {{session_dst_ip}} {{session_dscp}} {{session_ttl}} --policer {{policer_name}}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @stcheng . It seems that on public master and 201811 images this command is not supported (see below). Is sonic-utilities submodule pointer going to be updated soon?

Log:

"cmd": "config mirror_session add TEST_POLICER_SESSION 1.1.1.1 2.2.2.2 8 1 --policer TEST_POLICER"
"stderr": "Error: no such option: --policer",

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mykolaf I'll update the sonic-utilities pointer very soon

become: yes

- name: Create an ACL table with MIRROR_DSCP type
shell: config acl add table {{dscp_table_name}} "MIRROR_DSCP" --description "EVERFLOW_TEST"
become: yes

- name: Create a rule with DSCP value and mask
shell: |
redis-cli -n 4 hmset "ACL_RULE|{{dscp_table_name}}|RULE_1" "PRIORITY" "9999" "MIRROR_ACTION" "{{policer_session_name}}" "DSCP" "8/56"
become: yes

- name: "Start PTF runner"
include: roles/test/tasks/ptf_runner.yml
vars:
ptf_test_name: EVERFLOW Policer Test
ptf_test_dir: acstests
ptf_test_path: everflow_policer_test.EverflowPolicerTest
ptf_platform: remote
ptf_platform_dir: ptftests
ptf_test_params:
- asic_type='{{sonic_asic_type}}'
- hwsku='{{sonic_hwsku}}'
- router_mac='{{ansible_Ethernet0['macaddress']}}'
- src_port='{{src_port_ptf_id}}'
- dst_ports='{{",".join((spine_ptf_ports))}}'
- dst_mirror_ports='{{dst_port_1_ptf_id}}'
ptf_extra_options: "--relax --debug info"

always:
- name: Remove route
shell: vtysh -e "conf t" -e "no ip route {{ session_prefix_1 }} {{ neighbor_info_1['addr'] }}"
ignore_errors: yes
become: yes

- name: Create a policer
shell: |
redis-cli -n 4 del "POLICER|{{policer_name}}"
ignore_errors: yes
become: yes

- name: Create a policer enforced mirror session
shell: |
config mirror_session remove {{policer_session_name}}
ignore_errors: yes
become: yes

- name: Create an ACL table with MIRROR_DSCP type
shell: config acl remove table {{dscp_table_name}}
ignore_errors: yes
become: yes

- name: Create a rule with DSCP value and mask
shell: |
redis-cli -n 4 del "ACL_RULE|{{dscp_table_name}}|RULE_1"
ignore_errors: yes
become: yes