Skip to content

Commit b0b455b

Browse files
committed
test: add MixedTrafficTest, TunnelUnknownProtoTest, TtlBoundaryTest, fix comments/docs
Signed-off-by: An <aqnguyen96@gmail.com>
1 parent 6ad9bb6 commit b0b455b

File tree

1 file changed

+100
-4
lines changed

1 file changed

+100
-4
lines changed

exercises/basic_tunnel/ptf/basic_tunnel.py

Lines changed: 100 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
from ptf.base_tests import BaseTest
2626
from scapy.all import IP, TCP, Ether, Packet, ShortField, bind_layers
2727

28+
# Custom Tunnel
2829
TYPE_MYTUNNEL = 0x1212
2930
TYPE_IPV4 = 0x0800
3031

@@ -37,6 +38,7 @@ class MyTunnel(Packet):
3738
bind_layers(Ether, MyTunnel, type=TYPE_MYTUNNEL)
3839
bind_layers(MyTunnel, IP, proto_id=TYPE_IPV4)
3940

41+
4042
# Import p4runtime_lib from the tutorials repo utils directory
4143
sys.path.append(
4244
os.path.join(os.path.dirname(os.path.abspath(__file__)), "../../../utils/")
@@ -46,6 +48,7 @@ class MyTunnel(Packet):
4648
from p4runtime_lib.switch import ShutdownAllSwitchConnections
4749

4850

51+
# Configure Logging
4952
logger = logging.getLogger(None)
5053
handler = logging.StreamHandler()
5154
handler.setLevel(logging.INFO)
@@ -60,25 +63,39 @@ def setUp(self):
6063
self.dataplane = ptf.dataplane_instance
6164
self.dataplane.flush()
6265

66+
logging.debug("BasicTunnelTest.setUp()")
67+
68+
# Get test parameters
6369
grpc_addr = tu.test_param_get("grpcaddr") or "localhost:9559"
6470
p4info_txt_fname = tu.test_param_get("p4info")
6571
p4prog_binary_fname = tu.test_param_get("config")
6672

73+
# Create P4Info helper for building the table entries
6774
self.p4info_helper = p4runtime_lib.helper.P4InfoHelper(p4info_txt_fname)
75+
76+
# Connect to the switch via gRPC
6877
self.sw = p4runtime_lib.bmv2.Bmv2SwitchConnection(
6978
name="s1",
7079
address=grpc_addr,
7180
device_id=0,
72-
proto_dump_file="logs/s1-p4runtime-requests.txt",
73-
)
81+
proto_dump_file="logs/s1-p4runtime-requests.txt")
82+
83+
# Establish as master controller
7484
self.sw.MasterArbitrationUpdate()
85+
86+
# Load the P4 Program onto the switch
7587
self.sw.SetForwardingPipelineConfig(
76-
p4info=self.p4info_helper.p4info, bmv2_json_file_path=p4prog_binary_fname
77-
)
88+
p4info=self.p4info_helper.p4info, bmv2_json_file_path=p4prog_binary_fname)
7889

7990
def tearDown(self):
91+
logging.debug("BasicTunnelTest.tearDown()")
8092
ShutdownAllSwitchConnections()
8193

94+
95+
######################################################################
96+
# Helper function to add entries to ipv4_lpm table
97+
######################################################################
98+
8299
def add_ipv4_lpm_entry(self, ipv4_addr_str, prefix_len, dst_mac_str, port):
83100
table_entry = self.p4info_helper.buildTableEntry(
84101
table_name="MyIngress.ipv4_lpm",
@@ -99,6 +116,7 @@ def add_tunnel_entry(self, dst_id, port):
99116

100117

101118
class Ipv4DropOnMissTest(BasicTunnelTest):
119+
"""Verify that a plain IPv4 packet is dropped when no LPM table entry exists."""
102120
def runTest(self):
103121
pkt = tu.simple_tcp_packet(
104122
eth_src="ee:cd:00:7e:70:00",
@@ -111,6 +129,7 @@ def runTest(self):
111129

112130

113131
class Ipv4ForwardTest(BasicTunnelTest):
132+
"""Verify that a plain IPv4 packet is forwarded correctly with one table entry."""
114133
def runTest(self):
115134
in_dmac = "ee:30:ca:9d:1e:00"
116135
in_smac = "ee:cd:00:7e:70:00"
@@ -131,6 +150,7 @@ def runTest(self):
131150

132151

133152
class TunnelForwardTest(BasicTunnelTest):
153+
"""Verify that a tunneled packet is forwarded correctly when a valid table entry exists."""
134154
def runTest(self):
135155
in_pkt = (
136156
Ether(src="00:11:22:33:44:55", dst="ff:ff:ff:ff:ff:ff", type=TYPE_MYTUNNEL)
@@ -145,6 +165,7 @@ def runTest(self):
145165

146166

147167
class TunnelDropOnMissTest(BasicTunnelTest):
168+
"""Verify that a tunneled packet is dropped when no matching table entry exists."""
148169
def runTest(self):
149170
in_pkt = (
150171
Ether(src="00:11:22:33:44:66", dst="ff:ff:ff:ff:ff:ff", type=TYPE_MYTUNNEL)
@@ -155,3 +176,78 @@ def runTest(self):
155176
)
156177
tu.send_packet(self, 0, in_pkt)
157178
tu.verify_no_other_packets(self)
179+
180+
181+
class TtlBoundaryTest(BasicTunnelTest):
182+
"""Verify IPv4 TTL is decremented to 0 correctly when input TTL is 1."""
183+
def runTest(self):
184+
in_dmac = "ee:30:ca:9d:1e:00"
185+
in_smac = "ee:cd:00:7e:70:00"
186+
ip_dst = "10.0.9.9"
187+
ig_port = 1
188+
eg_port = 3
189+
out_dmac = "08:00:00:00:09:99"
190+
191+
self.add_ipv4_lpm_entry(ip_dst, 32, out_dmac, eg_port)
192+
193+
pkt = tu.simple_tcp_packet(
194+
eth_src=in_smac, eth_dst=in_dmac,
195+
ip_dst=ip_dst, ip_ttl=1
196+
)
197+
exp_pkt = tu.simple_tcp_packet(
198+
eth_src=in_dmac, eth_dst=out_dmac,
199+
ip_dst=ip_dst, ip_ttl=0
200+
)
201+
tu.send_packet(self, ig_port, pkt)
202+
tu.verify_packets(self, exp_pkt, [eg_port])
203+
204+
205+
class TunnelUnknownProtoTest(BasicTunnelTest):
206+
"""Verify tunnel packet with non-IPv4 proto_id is still forwarded by dst_id."""
207+
def runTest(self):
208+
self.add_tunnel_entry(dst_id=5, port=2)
209+
210+
pkt = (
211+
Ether(src="00:11:22:33:44:55", dst="ff:ff:ff:ff:ff:ff", type=TYPE_MYTUNNEL)
212+
/ MyTunnel(proto_id=0x9999, dst_id=5)
213+
/ "unknown-proto-payload"
214+
)
215+
tu.send_packet(self, 0, pkt)
216+
tu.verify_packets(self, pkt, [2])
217+
218+
219+
class MixedTrafficTest(BasicTunnelTest):
220+
"""Verify IPv4 and tunnel traffic are handled independently correctly via separate tables."""
221+
def runTest(self):
222+
in_dmac = "ee:30:ca:9d:1e:00"
223+
in_smac = "ee:cd:00:7e:70:00"
224+
ip_dst = "10.0.2.2"
225+
out_dmac = "08:00:00:00:02:22"
226+
ipv4_port = 2
227+
tunnel_port = 3
228+
229+
# add both table entries
230+
self.add_ipv4_lpm_entry(ip_dst, 32, out_dmac, ipv4_port)
231+
self.add_tunnel_entry(dst_id=2, port=tunnel_port)
232+
233+
# test plain IPv4 which should hit ipv4_lpm table
234+
ipv4_pkt = tu.simple_tcp_packet(
235+
eth_src=in_smac, eth_dst=in_dmac,
236+
ip_dst=ip_dst, ip_ttl=64
237+
)
238+
exp_ipv4_pkt = tu.simple_tcp_packet(
239+
eth_src=in_dmac, eth_dst=out_dmac,
240+
ip_dst=ip_dst, ip_ttl=63
241+
)
242+
tu.send_packet(self, 1, ipv4_pkt)
243+
tu.verify_packets(self, exp_ipv4_pkt, [ipv4_port])
244+
245+
# test tunnel packet which should hit myTunnel_exact table
246+
tunnel_pkt = (
247+
Ether(src="00:11:22:33:44:55", dst="ff:ff:ff:ff:ff:ff", type=TYPE_MYTUNNEL)
248+
/ MyTunnel(proto_id=TYPE_IPV4, dst_id=2)
249+
/ IP(src="10.0.1.1", dst="10.0.3.3", ttl=64)
250+
/ TCP(sport=12345, dport=1234)
251+
)
252+
tu.send_packet(self, 0, tunnel_pkt)
253+
tu.verify_packets(self, tunnel_pkt, [tunnel_port])

0 commit comments

Comments
 (0)