-
Notifications
You must be signed in to change notification settings - Fork 444
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
Repair the static DPDK PTF tests. #4210
Merged
Merged
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,170 +16,168 @@ | |
|
||
# Andy Fingerhut, [email protected] | ||
|
||
import logging | ||
import pprint | ||
import queue | ||
import time | ||
from enum import Enum | ||
from pathlib import Path | ||
|
||
import ptf | ||
import ptf.testutils as tu | ||
from ptf.base_tests import BaseTest | ||
import p4runtime_sh.shell as sh | ||
import p4runtime_sh.utils as shutils | ||
import p4runtime_sh.p4runtime as p4rt | ||
from ptf import testutils as ptfutils | ||
from ptf.mask import Mask | ||
from ptf.packet import * | ||
|
||
# The base_test.py path is relative to the test file, this should be improved | ||
FILE_DIR = Path(__file__).resolve().parent | ||
BASE_TEST_PATH = FILE_DIR.joinpath("../../backends/dpdk/base_test.py") | ||
sys.path.append(str(BASE_TEST_PATH)) | ||
import base_test as bt | ||
|
||
# Bsed on https://github.com/jafingerhut/p4-guide/blob/master/ipdk/23.01/add_on_miss0/ptf-tests/ptf-test1.py | ||
# This global variable ensure that the forwarding pipeline will only be pushed once in one tes | ||
PIPELINE_PUSHED = False | ||
|
||
|
||
logger = logging.getLogger(None) | ||
ch = logging.StreamHandler() | ||
ch.setLevel(logging.INFO) | ||
# create formatter and add it to the handlers | ||
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') | ||
ch.setFormatter(formatter) | ||
logger.addHandler(ch) | ||
class AbstractTest(bt.P4RuntimeTest): | ||
EnumColor = Enum("EnumColor", ["GREEN", "YELLOW", "RED"], start=0) | ||
|
||
pp = pprint.PrettyPrinter(indent=4) | ||
|
||
|
||
class AbstractIdleTimeoutTest(BaseTest): | ||
def setUp(self): | ||
# Setting up PTF dataplane | ||
self.dataplane = ptf.dataplane_instance | ||
self.dataplane.flush() | ||
|
||
logging.info("AbstractIdleTimeoutTest.setUp()") | ||
grpc_addr = tu.test_param_get("grpcaddr") | ||
if grpc_addr is None: | ||
grpc_addr = 'localhost:9559' | ||
certs_dir = '/usr/share/stratum/certs' | ||
root_certificate = certs_dir + '/ca.crt' | ||
private_key = certs_dir + '/client.key' | ||
certificate_chain = certs_dir + '/client.crt' | ||
# Default to insecure | ||
ssl_opts = p4rt.SSLOptions(True, root_certificate, certificate_chain, | ||
private_key) | ||
sh.setup(device_id=1, | ||
grpc_addr=grpc_addr, | ||
election_id=(0, 1), | ||
ssl_options=ssl_opts) | ||
bt.P4RuntimeTest.setUp(self) | ||
global PIPELINE_PUSHED | ||
if not PIPELINE_PUSHED: | ||
success = bt.P4RuntimeTest.updateConfig(self) | ||
assert success | ||
PIPELINE_PUSHED = True | ||
packet_wait_time = ptfutils.test_param_get("packet_wait_time") | ||
if not packet_wait_time: | ||
self.packet_wait_time = 0.1 | ||
else: | ||
self.packet_wait_time = float(packet_wait_time) | ||
|
||
def tearDown(self): | ||
logging.info("IdleTimeoutTest.tearDown()") | ||
sh.teardown() | ||
bt.P4RuntimeTest.tearDown(self) | ||
|
||
def setupCtrlPlane(self): | ||
pass | ||
|
||
def sendPacket(self): | ||
pass | ||
|
||
def verifyPackets(self): | ||
pass | ||
|
||
@bt.autocleanup | ||
def runTestImpl(self): | ||
self.setupCtrlPlane() | ||
logger.info("Sending Packet ...") | ||
bt.testutils.log.info("Sending Packet ...") | ||
self.sendPacket() | ||
logger.info("Verifying Packet ...") | ||
bt.testutils.log.info("Verifying Packet ...") | ||
self.verifyPackets() | ||
|
||
|
||
############################################################# | ||
# Define a few small helper functions that help construct | ||
# parameters for the table_add() method. | ||
############################################################# | ||
|
||
def entry_count(table_name): | ||
te = sh.TableEntry(table_name) | ||
n = 0 | ||
for x in te.read(): | ||
n = n + 1 | ||
return n | ||
|
||
def init_key_from_read_tableentry(read_te): | ||
new_te = sh.TableEntry(read_te.name) | ||
# This is only written to work for tables where all key fields are | ||
# match_kind exact. | ||
for f in read_te.match._fields: | ||
new_te.match[f] = '%d' % (int.from_bytes(read_te.match[f].exact.value, 'big')) | ||
return new_te | ||
|
||
def delete_all_entries(tname): | ||
te = sh.TableEntry(tname) | ||
for e in te.read(): | ||
d = init_key_from_read_tableentry(e) | ||
d.delete() | ||
|
||
def add_ipv4_host_entry_action_send(ipv4_addr_str, port_int): | ||
te = sh.TableEntry('ipv4_host')(action='send') | ||
te.match['dst_addr'] = '%s' % (ipv4_addr_str) | ||
te.action['port'] = '%d' % (port_int) | ||
te.insert() | ||
|
||
class OneEntryTest(AbstractTest): | ||
def entry_count(self, table_name): | ||
req, table = self.make_table_read_request(table_name) | ||
n = 0 | ||
for response in self.response_dump_helper(req): | ||
n += len(response.entities) | ||
return n | ||
|
||
class OneEntryTest(AbstractIdleTimeoutTest): | ||
def delete_all_table_entries(self, table_name): | ||
req, _ = self.make_table_read_request(table_name) | ||
for response in self.response_dump_helper(req): | ||
for entity in response.entities: | ||
assert entity.HasField("table_entry") | ||
self.delete_table_entry(entity.table_entry) | ||
return | ||
return | ||
|
||
def sendPacket(self): | ||
in_dmac = 'ee:30:ca:9d:1e:00' | ||
in_smac = 'ee:cd:00:7e:70:00' | ||
ip_src_addr = '1.1.1.1' | ||
ip_dst_addr = '2.2.2.2' | ||
in_dmac = "ee:30:ca:9d:1e:00" | ||
in_smac = "ee:cd:00:7e:70:00" | ||
ip_src_addr = "1.1.1.1" | ||
ip_dst_addr = "2.2.2.2" | ||
ig_port = 0 | ||
sport = 59597 | ||
dport = 7503 | ||
pkt_in = tu.simple_tcp_packet(eth_src=in_smac, eth_dst=in_dmac, | ||
ip_src=ip_src_addr, ip_dst=ip_dst_addr, | ||
tcp_sport=sport, tcp_dport=dport) | ||
|
||
pkt_in = ptfutils.simple_tcp_packet( | ||
eth_src=in_smac, | ||
eth_dst=in_dmac, | ||
ip_src=ip_src_addr, | ||
ip_dst=ip_dst_addr, | ||
tcp_sport=sport, | ||
tcp_dport=dport, | ||
) | ||
|
||
# Send in a first packet that should experience a miss on | ||
# table ct_tcp_table, cause a new entry to be added by the | ||
# data plane with a 30-second expiration time, and be | ||
# forwarded with a change to its source MAC address that the | ||
# add_on_miss0.p4 program uses to indicate that a miss | ||
# occurred. | ||
logging.info("Sending packet #1") | ||
tu.send_packet(self, ig_port, pkt_in) | ||
bt.testutils.log.info("Sending packet #1") | ||
ptfutils.send_packet(self, ig_port, pkt_in) | ||
first_pkt_time = time.time() | ||
|
||
def verifyPackets(self): | ||
in_dmac = 'ee:30:ca:9d:1e:00' | ||
in_smac = 'ee:cd:00:7e:70:00' | ||
ip_src_addr = '1.1.1.1' | ||
ip_dst_addr = '2.2.2.2' | ||
in_dmac = "ee:30:ca:9d:1e:00" | ||
in_smac = "ee:cd:00:7e:70:00" | ||
ip_src_addr = "1.1.1.1" | ||
ip_dst_addr = "2.2.2.2" | ||
sport = 59597 | ||
dport = 7503 | ||
# add_on_miss0.p4 replaces least significant 8 bits of source | ||
# MAC address with 0xf1 on a hit of table ct_tcp_table, or | ||
# 0xa5 on a miss. | ||
out_smac_for_miss = in_smac[:-2] + 'a5' | ||
out_smac_for_miss = in_smac[:-2] + "a5" | ||
eg_port = 1 | ||
exp_pkt_for_miss = \ | ||
tu.simple_tcp_packet(eth_src=out_smac_for_miss, eth_dst=in_dmac, | ||
ip_src=ip_src_addr, ip_dst=ip_dst_addr, | ||
tcp_sport=sport, tcp_dport=dport) | ||
exp_pkt_for_miss = ptfutils.simple_tcp_packet( | ||
eth_src=out_smac_for_miss, | ||
eth_dst=in_dmac, | ||
ip_src=ip_src_addr, | ||
ip_dst=ip_dst_addr, | ||
tcp_sport=sport, | ||
tcp_dport=dport, | ||
) | ||
|
||
# Check hit not tested for now for simplicity | ||
# out_smac_for_hit = in_smac[:-2] + 'f1' | ||
# out_smac_for_hit = in_smac[:-2] + "f1" | ||
# exp_pkt_for_hit = \ | ||
# tu.simple_tcp_packet(eth_src=out_smac_for_hit, eth_dst=in_dmac, | ||
# ptfutils.simple_tcp_packet(eth_src=out_smac_for_hit, eth_dst=in_dmac, | ||
# ip_src=ip_src_addr, ip_dst=ip_dst_addr, | ||
# tcp_sport=sport, tcp_dport=dport) | ||
|
||
|
||
tu.verify_packets(self, exp_pkt_for_miss, [eg_port]) | ||
logging.info(" packet experienced a miss in ct_tcp_table as expected") | ||
ptfutils.verify_packets(self, exp_pkt_for_miss, [eg_port]) | ||
bt.testutils.log.info("packet experienced a miss in ct_tcp_table as expected") | ||
|
||
bt.testutils.log.info("Attempting to delete all entries in ipv4_host") | ||
# TODO: This code does not seem functional? | ||
# self.delete_all_table_entries("MainControlImpl.ipv4_host") | ||
# assert self.entry_count("MainControlImpl.ipv4_host") == 0 | ||
|
||
def setupCtrlPlane(self): | ||
ig_port = 0 | ||
eg_port = 1 | ||
|
||
ip_src_addr = '1.1.1.1' | ||
ip_dst_addr = '2.2.2.2' | ||
|
||
logging.info("Attempting to delete all entries in ipv4_host") | ||
delete_all_entries('ipv4_host') | ||
logging.info("Attempting to add entries to ipv4_host") | ||
add_ipv4_host_entry_action_send(ip_src_addr, ig_port) | ||
add_ipv4_host_entry_action_send(ip_dst_addr, eg_port) | ||
logging.info("Now ipv4_host contains %d entries" | ||
"" % (entry_count('ipv4_host'))) | ||
ip_src_addr = 16843009 # "1.1.1.1" | ||
ip_dst_addr = 33686018 # "2.2.2.2" | ||
table_name = "MainControlImpl.ipv4_host" | ||
|
||
assert self.entry_count(table_name) == 0 | ||
bt.testutils.log.info("Attempting to add entries to ipv4_host") | ||
self.table_add( | ||
(table_name, [self.Exact("hdr.ipv4.dst_addr", ip_src_addr)]), | ||
("MainControlImpl.send", [("port", ig_port)]), | ||
) | ||
self.table_add( | ||
(table_name, [self.Exact("hdr.ipv4.dst_addr", ip_dst_addr)]), | ||
("MainControlImpl.send", [("port", eg_port)]), | ||
) | ||
entry_count = self.entry_count(table_name) | ||
bt.testutils.log.info("Now ipv4_host contains %d entries" "", entry_count) | ||
assert entry_count == 2 | ||
|
||
def runTest(self): | ||
self.runTestImpl() | ||
|
||
|
||
|
||
|
||
|
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
@jafingerhut I am unable to delete table entries on the P4Runtime interface for the DPDK SoftNIC. Even when I read the entries from the table, then try to delete those exact same entries I am getting a "not found" error. Is this a known issue?
The P4Runtme shell code also has the same issue, but it was never uncovered because it was only ever used on tables with no entries.
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 can double-check, but if I recall correctly, the current DPDK implementation does not support adding or deleting entries from the control plane specifically for add-on-miss tables. For add-on-miss tables, it only supports adding and deleting entries from the data plane.
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.
Ah good to know. Strangely enough I am able to add entries, but I can not remove them.