Skip to content

Commit b23fd50

Browse files
gollarharsharraghav-cisco
authored andcommitted
BFD+VXLAN Automation (#6212)
1. Updated the traffic script to pump all the packets of an iteration in one go, and then wait in a timed-loop for reply packets. This speeds up the traffic script greatly. The full runtime is now 3.5 hours. 2. Added --include_long_tests argument, so that user can run basic tests by default(45 minutes runtime for all 4 encap types). If the long tests are included, the total runtime is now 3.5 hours. 3. Updated the scripts for improved pylint score. The new scores: a) test_vxlan_ecmp.py: 8.89/10 b) vxlan_traffic.py : 7.18/10 c) vxlan_ecmp_utils.py : 9.31/10 * Re-formatted and fixed the scripts to pass the pre-commit checks. All flake8 checks are clean. (venv3) RRAGHAV-M-C3KR:sonic-mgmt-hgolla root# flake8 ansible/roles/test/files/ptftests/vxlan_traffic.py (venv3) RRAGHAV-M-C3KR:sonic-mgmt-hgolla root# flake8 ansible/roles/test/files/ptftests/bfd_responder.py (venv3) RRAGHAV-M-C3KR:sonic-mgmt-hgolla root# flake8 tests/vxlan/test_vxlan_ecmp.py (venv3) RRAGHAV-M-C3KR:sonic-mgmt-hgolla root# flake8 tests/vxlan/vxlan_ecmp_utils.py (venv3) RRAGHAV-M-C3KR:sonic-mgmt-hgolla root# flake8 tests/vxlan/conftest.py (venv3) RRAGHAV-M-C3KR:sonic-mgmt-hgolla root# Run and verified: iINFO:root:Can not get Allure report URL. Please check logs =========================== short test summary info ============================ SKIPPED [4] vxlan/test_vxlan_ecmp.py:1962: This test will be run only if '--include_crm=True' is provided. SKIPPED [4] vxlan/test_vxlan_ecmp.py:1908: This test will be run only if '--include_crm=True' is provided. SKIPPED [4] vxlan/test_vxlan_ecmp.py:1948: This test will be run only if '--include_crm=True' is provided. ERROR vxlan/test_vxlan_ecmp.py::Test_VxLAN_Crm::test_crm_128_group_members[v6_in_v6] ============= 104 passed, 12 skipped, 1 error in 10992.56 seconds ============== Co-authored-by: rraghav-cisco <rraghav@cisco.com>
1 parent 7120af9 commit b23fd50

8 files changed

Lines changed: 3146 additions & 982 deletions

File tree

ansible/roles/test/files/helpers/bfd_responder.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,3 +182,4 @@ def main():
182182

183183
if __name__ == '__main__':
184184
main()
185+
Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
# PTF bfd responder. Responds to any BFD packet that we received.
2+
# Uses a monitor file as input. The monitor file has 2 lines:
3+
# Line 1: list of port indices to monitor
4+
# Line 2: list of ip addresses to respond to.
5+
6+
import ptf
7+
import time
8+
import ptf.packet as scapy
9+
from ptf.base_tests import BaseTest
10+
from scapy.contrib.bfd import BFD
11+
from ptf.testutils import (send_packet, test_params_get)
12+
from ipaddress import ip_address, IPv4Address, IPv6Address
13+
session_timeout = 1
14+
15+
16+
class BFD_Responder(BaseTest):
17+
def __init__(self):
18+
BaseTest.__init__(self)
19+
self.DEFAULT_PKT_LEN = 100
20+
self.sessions = {}
21+
self.local_disc_base = 0xcdba0000
22+
self.local_src_port = 14000
23+
24+
def setUp(self):
25+
self.dataplane = ptf.dataplane_instance
26+
self.test_params = test_params_get()
27+
self.dut_mac = self.test_params['dut_mac']
28+
self.dut_loop_ips = self.test_params['dut_loop_ips']
29+
for ipaddr in self.dut_loop_ips:
30+
if isinstance(ip_address(ipaddr.decode()), IPv4Address):
31+
self.dut_loop_ipv4 = ipaddr
32+
if isinstance(ip_address(ipaddr.decode()), IPv6Address):
33+
self.dut_loop_ipv6 = ipaddr
34+
self.monitor_file = self.test_params['monitor_file']
35+
36+
def respond_to_packet(self, port_number, received_pkt):
37+
received_pkt = scapy.Ether(received_pkt)
38+
args = {}
39+
args['dst_mac'] = received_pkt['Ether'].dst
40+
args['version'] = received_pkt['BFD'].version
41+
args['diag'] = received_pkt['BFD'].diag
42+
args['sta'] = received_pkt['BFD'].sta
43+
args['flags'] = received_pkt['BFD'].flags
44+
args['detect_multi'] = received_pkt['BFD'].detect_multi
45+
args['len'] = received_pkt['BFD'].len
46+
args['my_discriminator'] = received_pkt['BFD'].my_discriminator
47+
args['your_discriminator'] = received_pkt['BFD'].your_discriminator
48+
args['min_tx_interval'] = received_pkt['BFD'].min_tx_interval
49+
args['min_rx_interval'] = received_pkt['BFD'].min_rx_interval
50+
args['echo_rx_interval'] = received_pkt['BFD'].echo_rx_interval
51+
52+
pkt = BFD(args)
53+
count = send_packet(self, port_number, str(pkt))
54+
if count == 0:
55+
raise RuntimeError(
56+
"send_packet failed args:port_number{}, "
57+
"dp_tuple:{}".format(port_number, str(pkt)))
58+
59+
def runTest(self):
60+
while True:
61+
valid_monit_file = True
62+
with open(self.monitor_file) as fd:
63+
full_strings = fd.readlines()
64+
try:
65+
ports_to_monitor = full_strings[0].strip()
66+
all_monitored_addresses = full_strings[1].strip()
67+
except IndexError:
68+
valid_monit_file = False
69+
if ports_to_monitor == "" or all_monitored_addresses == "":
70+
valid_monit_file = False
71+
72+
if not valid_monit_file:
73+
time.sleep(1)
74+
continue
75+
ports_to_monitor = [int(x) for x in ports_to_monitor.split(',')]
76+
all_monitored_addresses = all_monitored_addresses.split(',')
77+
78+
result = self.dataplane.poll(device_number=0, timeout=0.1)
79+
if not isinstance(result, self.dataplane.PollSuccess) or \
80+
result.port not in ports_to_monitor or \
81+
"UDP" not in scapy.Ether(result.packet):
82+
continue
83+
if scapy.Ether(result.packet)['UDP'].dport != 4784:
84+
continue
85+
received_pkt = result.packet
86+
port_number = result.port
87+
mac_src, mac_dst, ip_src, ip_dst, bfd_remote_disc, bfd_state = \
88+
self.extract_bfd_info(received_pkt)
89+
if ip_dst not in all_monitored_addresses:
90+
continue
91+
try:
92+
session = self.sessions[ip_dst]
93+
except KeyError:
94+
self.sessions[ip_dst] = {}
95+
96+
if bfd_state == 3:
97+
count = send_packet(self, result.port, str(session["pkt"]))
98+
if count == 0:
99+
raise RuntimeError(
100+
"send_packet failed args:port_number{}, "
101+
"dp_tuple:{}".format(port_number, str(session['pkt'])))
102+
103+
if bfd_state == 2:
104+
continue
105+
106+
session = {}
107+
session['addr'] = ip_dst
108+
session['remote_addr'] = ip_src
109+
session['intf'] = result.port
110+
session['multihop'] = True
111+
session['mac'] = mac_dst
112+
session['pkt'] = ''
113+
session["src_port"] = self.local_src_port
114+
self.local_disc_base += 1
115+
self.local_src_port += 1
116+
session['my_disc'] = self.local_disc_base
117+
session["other_disc"] = bfd_remote_disc
118+
119+
bfd_pkt_init = self.craft_bfd_packet(
120+
session['my_disc'],
121+
received_pkt,
122+
mac_src,
123+
mac_dst,
124+
ip_src,
125+
ip_dst,
126+
bfd_remote_disc,
127+
2)
128+
count = send_packet(self, session['intf'], str(bfd_pkt_init))
129+
if count == 0:
130+
raise RuntimeError(
131+
"send_packet failed args:port_number{}, "
132+
"dp_tuple:{}".format(port_number, str(bfd_pkt_init)))
133+
bfd_pkt_init.payload.payload.payload.load.sta = 3
134+
session["pkt"] = bfd_pkt_init
135+
self.sessions[ip_dst] = session
136+
137+
def extract_bfd_info(self, data):
138+
# remote_mac, remote_ip, request_ip, op_type
139+
ether = scapy.Ether(data)
140+
mac_src = ether.src
141+
mac_dst = ether.dst
142+
ip_src = ether.payload.src
143+
ip_dst = ether.payload.dst
144+
bfdpkt = BFD(ether.payload.payload.payload.load)
145+
bfd_remote_disc = bfdpkt.my_discriminator
146+
bfd_state = bfdpkt.sta
147+
return mac_src, mac_dst, ip_src, ip_dst, bfd_remote_disc, bfd_state
148+
149+
def craft_bfd_packet(self,
150+
my_discriminator,
151+
data,
152+
mac_src,
153+
mac_dst,
154+
ip_src,
155+
ip_dst,
156+
bfd_remote_disc,
157+
bfd_state):
158+
ethpart = scapy.Ether(data)
159+
bfdpart = BFD(ethpart.payload.payload.payload.load)
160+
bfdpart.my_discriminator = my_discriminator
161+
bfdpart.your_discriminator = bfd_remote_disc
162+
bfdpart.sta = bfd_state
163+
164+
ethpart.payload.payload.payload.load = bfdpart
165+
ethpart.src = mac_dst
166+
ethpart.dst = mac_src
167+
ethpart.payload.src = ip_dst
168+
ethpart.payload.dst = ip_src
169+
return ethpart

0 commit comments

Comments
 (0)