Skip to content

Commit

Permalink
[everflow_testbed] extend test to cover egress mirroring (#1094)
Browse files Browse the repository at this point in the history
* [everflow_testbed] extend test to cover ingress/egress mirroring on ingress/egress ACL table based on DUT capabilities

Signed-off-by: Stepan Blyschak <stepanb@mellanox.com>

* fix ptf port id passing

Signed-off-by: Stepan Blyschak <stepanb@mellanox.com>

* fix test case #4

Signed-off-by: Stepan Blyschak <stepanb@mellanox.com>

* fix testcase 3,4 description

Signed-off-by: Stepan Blyschak <stepanb@mellanox.com>

* fix everflow policer test for egress mirroring test

Signed-off-by: Stepan Blyschak <stepanb@mellanox.com>

* address review comments

Signed-off-by: Stepan Blyschak <stepanb@mellanox.com>
  • Loading branch information
stepanblyschak authored and liat-grozovik committed Oct 29, 2019
1 parent 76512b5 commit 1d726e3
Show file tree
Hide file tree
Showing 20 changed files with 548 additions and 397 deletions.
53 changes: 53 additions & 0 deletions ansible/library/switch_capabilities_facts.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#!/usr/bin/python

import swsssdk

DOCUMENTATION = '''
module: switch_capability_facts
version_added: "1.0"
author: Stepan Blyschak (stepanb@mellanox.com)
short_description: Retrieve switch capability information
'''

EXAMPLES = '''
- name: Get switch capability facts
switch_capability_facts:
'''


class SwitchCapabilityModule(object):
def __init__(self):
self.module = AnsibleModule(
argument_spec=dict(
),
supports_check_mode=True)

self.out = None
self.facts = {}

return

def run(self):
"""
Main method of the class
"""
self.facts['switch_capabilities'] = {}

conn = swsssdk.SonicV2Connector(host='127.0.0.1')
conn.connect(conn.STATE_DB)
keys = conn.keys(conn.STATE_DB, 'SWITCH_CAPABILITY|*')

for key in keys:
capab = conn.get_all(conn.STATE_DB, key)
self.facts['switch_capabilities'][key.split('|')[-1]] = capab

self.module.exit_json(ansible_facts=self.facts)


def main():
SwitchCapabilityModule().run()


from ansible.module_utils.basic import *
if __name__ == "__main__":
main()
23 changes: 19 additions & 4 deletions ansible/roles/test/files/acstests/everflow_policer_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ def setUp(self):
self.hwsku = self.test_params['hwsku']
self.asic_type = self.test_params['asic_type']
self.router_mac = self.test_params['router_mac']
self.mirror_stage = self.test_params['mirror_stage']
self.session_src_ip = "1.1.1.1"
self.session_dst_ip = "2.2.2.2"
self.session_ttl = 1
Expand Down Expand Up @@ -106,7 +107,15 @@ def checkMirroredFlow(self):
Mellanox crafts the GRE packets with extra information:
That is: 22 bytes extra information after the GRE header
"""
payload = self.base_pkt
payload = self.base_pkt.copy()
payload_mask = Mask(payload)

if self.mirror_stage == "egress":
payload['Ethernet'].src = self.router_mac
payload['IP'].ttl -= 1
payload_mask.set_do_not_care_scapy(scapy.Ether, "dst")
payload_mask.set_do_not_care_scapy(scapy.IP, "chksum")

if self.asic_type in ["mellanox"]:
import binascii
payload = binascii.unhexlify("0"*44) + str(payload) # Add the padding
Expand All @@ -130,17 +139,23 @@ def checkMirroredFlow(self):
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")
masked_exp_pkt.set_do_not_care(38*8, len(payload)*8) # don't match payload, payload will be matched by match_payload(pkt)

if self.asic_type in ["mellanox"]:
masked_exp_pkt.set_do_not_care(304, 176) # Mask the Mellanox specific inner header
def match_payload(pkt):
pkt = scapy.Ether(pkt).load
if self.asic_type in ["mellanox"]:
pkt = pkt[22:] # Mask the Mellanox specific inner header
pkt = scapy.Ether(pkt)

return dataplane.match_exp_pkt(payload_mask, pkt)

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:
if rcv_pkt is not None and match_payload(rcv_pkt):
count += 1
elif count == 0:
print "The first mirrored packet is not recieved"
Expand Down
16 changes: 15 additions & 1 deletion ansible/roles/test/files/acstests/everflow_tb_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,9 @@ def setUp(self):
self.src_port = int(float(self.test_params['src_port']))
self.dst_ports = [int(float(p)) for p in self.test_params['dst_ports'].split(",") if p]
self.expected_dst_mac = self.test_params.get('expected_dst_mac', None)
self.expect_received = self.test_params.get('expect_received', True)
self.acl_stage = self.test_params.get('acl_stage', 'ingress')
self.mirror_stage = self.test_params.get('mirror_stage', 'ingress')

testutils.add_filter(self.gre_type_filter)

Expand Down Expand Up @@ -106,7 +109,7 @@ def receivePacketOnPorts(self, ports=[], device_number=0):
return (match_index, rcv_pkt, received)


def runSendReceiveTest(self, pkt2send, src_port, destination_ports):
def sendReceive(self, pkt2send, src_port, destination_ports):
"""
@summary Send packet and verify it is received/not received on the expected ports
"""
Expand Down Expand Up @@ -149,7 +152,12 @@ def runSendReceiveTest(self, pkt2send, src_port, destination_ports):

inner_pkt = scapy.Ether(payload)

if self.mirror_stage == 'egress':
pkt2send['IP'].ttl -= 1 # expect mirrored packet on egress has TTL decremented

masked_inner_pkt = Mask(inner_pkt)
masked_inner_pkt.set_do_not_care_scapy(scapy.Ether, "dst")
masked_inner_pkt.set_do_not_care_scapy(scapy.Ether, "src")
if scapy.IP in inner_pkt:
masked_inner_pkt.set_do_not_care_scapy(scapy.IP, "chksum")

Expand All @@ -158,6 +166,12 @@ def runSendReceiveTest(self, pkt2send, src_port, destination_ports):

return dataplane.match_exp_pkt(masked_inner_pkt, pkt2send)

def runSendReceiveTest(self, pkt, src_port, dst_ports):
if self.expect_received:
return self.sendReceive(pkt, src_port, dst_ports)
else:
return not self.sendReceive(pkt, src_port, dst_ports)


@reportResults("Verify SRC IP match")
def verifySrcIp(self):
Expand Down
38 changes: 24 additions & 14 deletions ansible/roles/test/tasks/everflow_testbed.yml
Original file line number Diff line number Diff line change
@@ -1,19 +1,29 @@
- name: Apply Everflow configuration.
include: "roles/test/tasks/everflow_testbed/apply_config.yml"
tags: everflow_tb_configure
- name: Get switch capabilities
include: "roles/test/tasks/everflow_testbed/get_capabilities_info.yml"

- name: Run Everflow tests.
include: "roles/test/tasks/everflow_testbed/run_test.yml"
- name: Get general port information
include: "roles/test/tasks/everflow_testbed/get_general_port_info.yml"

- include: "roles/test/tasks/everflow_testbed/everflow_main.yml"
vars:
mirror_stage: "ingress"
acl_stage: "ingress"
when: test_ingress_mirror_on_ingress_acl == true

- include: "roles/test/tasks/everflow_testbed/everflow_main.yml"
vars:
dst_port_type: "tor"
tags: everflow_tb_test
mirror_stage: "egress"
acl_stage: "ingress"
when: test_egress_mirror_on_ingress_acl == true

- name: Run Everflow tests.
include: "roles/test/tasks/everflow_testbed/run_test.yml"
- include: "roles/test/tasks/everflow_testbed/everflow_main.yml"
vars:
dst_port_type: "spine"
tags: everflow_tb_test
mirror_stage: "ingress"
acl_stage: "egress"
when: test_ingress_mirror_on_egress_acl == true

- name: Clear Everflow configuration.
include: "roles/test/tasks/everflow_testbed/del_config.yml"
tags: everflow_tb_cleanup
- include: "roles/test/tasks/everflow_testbed/everflow_main.yml"
vars:
mirror_stage: "egress"
acl_stage: "egress"
when: test_egress_mirror_on_egress_acl == true
51 changes: 48 additions & 3 deletions ansible/roles/test/tasks/everflow_testbed/apply_config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,59 @@
tests_location: roles/test/tasks/everflow_testbed
testname: apply_config

- name: Create running directory
command: "mkdir -p {{ run_dir }}"

- name: Get session info.
include: roles/test/tasks/everflow_testbed/get_session_info.yml

- name: Copy ACL rules configuration file.
copy: src={{ tests_location }}/{{ testname}}/acl_rule_persistent.json dest={{ run_dir }}/
- name: Set Everflow table name
set_fact:
acl_table_name: "EVERFLOW"

- block:
- name: Init variables
set_fact:
acl_table_name: "EVERFLOW_EGRESS"
acl_table_ports: "{{ everflow_table_ports }}"
acl_table_stage: "{{ acl_stage }}"
acl_table_type: "MIRROR"

- name: Remove default SONiC Everflow table (since SONiC allows only one mirror table)
command: "config acl remove table EVERFLOW"
become: yes

- name: Set a flag that need recover config from config_db.json
set_fact:
recover_from_cfgdb_file: True

- name: Generate config for egress Everflow table
template:
src: "roles/test/templates/acltb_table.j2"
dest: "{{ run_dir }}/everflow_egress_table.json"

- name: Create egress Everflow table
command: "sonic-cfggen -j {{ run_dir }}/everflow_egress_table.json --write-to-db"
become: yes
when: acl_stage == "egress"

- name: Copy ACL rules configuration file
template:
src={{ tests_location }}/{{ testname}}/acl_rule_persistent.json.j2
dest={{ run_dir }}/acl_rule_persistent.json

- command: "config mirror_session add {{session_name}} {{session_src_ip}} {{session_dst_ip}} {{session_dscp}} {{session_ttl}} {{session_gre}} {{session_queue}}"
become: yes

- command: "acl-loader update full {{ run_dir }}/acl_rule_persistent.json --session_name={{ session_name }}"
- name: Set acl-loader command
set_fact:
load_rule_cmd: "acl-loader update full {{ run_dir }}/acl_rule_persistent.json --session_name={{ session_name }}"

- name: Append stage parameter if needed
set_fact:
load_rule_cmd: "{{ load_rule_cmd }} --mirror_stage={{ mirror_stage }}"
when: mirror_stage == "egress"

- name: Load ACL mirror rules
command: "{{ load_rule_cmd }}"
become: yes
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"acl": {
"acl-sets": {
"acl-set": {
"everflow": {
"{{ acl_table_name }}": {
"acl-entries": {
"acl-entry": {
"1": {
Expand Down
37 changes: 37 additions & 0 deletions ansible/roles/test/tasks/everflow_testbed/everflow_main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
- fail:
msg: "Mirror stage is not defined or invalid"
when: mirror_stage is not defined or mirror_stage not in ['ingress', 'egress']

- fail:
msg: "ACL stage is not defined or invalid"
when: acl_stage is not defined or acl_stage not in ['ingress', 'egress']

- name: Set flag that recover from config_db.json is needed (default - false)
set_fact:
recover_from_cfgdb_file: False

- name: Apply Everflow configuration.
include: "roles/test/tasks/everflow_testbed/apply_config.yml"
tags: everflow_tb_configure

- name: Run Everflow tests [tor].
include: "roles/test/tasks/everflow_testbed/run_test.yml"
vars:
dst_port_type: "tor"
tags: everflow_tb_test

- name: Run Everflow tests [spine].
include: "roles/test/tasks/everflow_testbed/run_test.yml"
vars:
dst_port_type: "spine"
tags: everflow_tb_test

- name: Clear Everflow configuration.
include: "roles/test/tasks/everflow_testbed/del_config.yml"
tags: everflow_tb_cleanup

- name: Reload config
include: "roles/test/tasks/common_tasks/reload_config.yml"
vars:
config_source: "config_db"
when: recover_from_cfgdb_file
27 changes: 27 additions & 0 deletions ansible/roles/test/tasks/everflow_testbed/everflow_ptf.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
- set_fact:
expect_received: True
when: expect_received is not defined

- name: Send traffic and verify that packets with correct Everflow header are {{ expect_received | ternary('', 'not') }} received on destination port {{ dst_port }}
include: roles/test/tasks/ptf_runner.yml
vars:
ptf_test_name: Everflow Test
ptf_test_dir: acstests
ptf_test_path: everflow_tb_test.EverflowTest
ptf_platform_dir: ptftests
ptf_platform: remote
ptf_test_params:
- asic_type='{{ sonic_asic_type }}'
- hwsku='{{ sonic_hwsku }}'
- router_mac='{{ ansible_Ethernet0['macaddress'] }}'
- src_port='{{ src_port_ptf_id }}'
- dst_ports='{{ dst_port_ptf_id }}'
- session_src_ip='{{ session_src_ip }}'
- session_dst_ip='{{ session_dst_ip }}'
- session_ttl='{{ session_ttl }}'
- session_dscp='{{ session_dscp }}'
- acl_stage='{{ acl_stage }}'
- mirror_stage='{{ mirror_stage }}'
- expect_received={{ expect_received }}
- verbose=True
ptf_extra_options: "--log-file /tmp/everflow_tb_test.EverflowTest.{{lookup('pipe','date +%Y-%m-%d-%H:%M:%S')}}.log"
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
- name: get switch capabilities
switch_capabilities_facts:

- name: initialize variables
set_fact:
test_mirror_v4: False
test_mirror_v6: False
test_ingress_mirror_on_ingress_acl: False
test_ingress_mirror_on_egress_acl: False
test_egress_mirror_on_egress_acl: False
test_egress_mirror_on_ingress_acl: False

- name: set flag if mirroring is supported
set_fact:
test_mirror_v4: True
when: switch_capabilities['switch']['MIRROR'] | lower == 'true'

- name: set flag if V6 mirroring is supported
set_fact:
test_mirror_v6: True
when: switch_capabilities['switch']['MIRRORV6'] | lower == 'true'

- name: set flag if ingress mirroring on ingress ACL is supported
set_fact:
test_ingress_mirror_on_ingress_acl: True
when: "{{ 'MIRROR_INGRESS_ACTION' in switch_capabilities['switch']['ACL_ACTIONS|INGRESS'] }}"

- name: set flag if egress mirroring on ingress ACL is supported
set_fact:
test_egress_mirror_on_ingress_acl: True
when: "{{ 'MIRROR_EGRESS_ACTION' in switch_capabilities['switch']['ACL_ACTIONS|INGRESS'] }}"

- name: set flag if ingress mirroring on egress ACL is supported
set_fact:
test_ingress_mirror_on_egress_acl: True
when: "{{ 'MIRROR_INGRESS_ACTION' in switch_capabilities['switch']['ACL_ACTIONS|EGRESS'] }}"

- name: set flag if egress mirroring on egress ACL is supported
set_fact:
test_egress_mirror_on_egress_acl: True
when: "{{ 'MIRROR_EGRESS_ACTION' in switch_capabilities['switch']['ACL_ACTIONS|EGRESS'] }}"

- debug: var=test_mirror_v4
- debug: var=test_mirror_v6
- debug: var=test_ingress_mirror_on_ingress_acl
- debug: var=test_ingress_mirror_on_egress_acl
- debug: var=test_egress_mirror_on_ingress_acl
- debug: var=test_egress_mirror_on_egress_acl

Loading

0 comments on commit 1d726e3

Please sign in to comment.