From 071b89ad30f864656fef0255d79371da0a7d3c86 Mon Sep 17 00:00:00 2001 From: Radostin Stoyanov Date: Thu, 24 Feb 2022 15:45:58 +0000 Subject: [PATCH] utils: show error message when priority is missing (#452) * p4runtime_lib/helper: use more appropriate variable names Suggested-by: Antonin Bas Signed-off-by: Radostin Stoyanov * utils: show error message when priority is missing A 'priority' field is required to order entries when the table's match key includes an optional, ternary or range match. Suggested-by: Andy Fingerhut Signed-off-by: Radostin Stoyanov --- utils/p4runtime_lib/helper.py | 18 ++++++++--------- utils/p4runtime_lib/simple_controller.py | 25 +++++++++++++++++++++++- utils/run_exercise.py | 4 +++- 3 files changed, 36 insertions(+), 11 deletions(-) diff --git a/utils/p4runtime_lib/helper.py b/utils/p4runtime_lib/helper.py index 29ea788..e05688a 100644 --- a/utils/p4runtime_lib/helper.py +++ b/utils/p4runtime_lib/helper.py @@ -101,17 +101,17 @@ class P4InfoHelper(object): exact = p4runtime_match.exact exact.value = encode(value, bitwidth) elif match_type == p4info_pb2.MatchField.LPM: - lpm = p4runtime_match.lpm - lpm.value = encode(value[0], bitwidth) - lpm.prefix_len = value[1] + lpm_entry = p4runtime_match.lpm + lpm_entry.value = encode(value[0], bitwidth) + lpm_entry.prefix_len = value[1] elif match_type == p4info_pb2.MatchField.TERNARY: - lpm = p4runtime_match.ternary - lpm.value = encode(value[0], bitwidth) - lpm.mask = encode(value[1], bitwidth) + ternary_entry = p4runtime_match.ternary + ternary_entry.value = encode(value[0], bitwidth) + ternary_entry.mask = encode(value[1], bitwidth) elif match_type == p4info_pb2.MatchField.RANGE: - lpm = p4runtime_match.range - lpm.low = encode(value[0], bitwidth) - lpm.high = encode(value[1], bitwidth) + range_entry = p4runtime_match.range + range_entry.low = encode(value[0], bitwidth) + range_entry.high = encode(value[1], bitwidth) else: raise Exception("Unsupported match type with type %r" % match_type) return p4runtime_match diff --git a/utils/p4runtime_lib/simple_controller.py b/utils/p4runtime_lib/simple_controller.py index 8788abd..ffce5c1 100755 --- a/utils/p4runtime_lib/simple_controller.py +++ b/utils/p4runtime_lib/simple_controller.py @@ -22,6 +22,8 @@ import sys from . import bmv2 from . import helper +from p4.config.v1 import p4info_pb2 + def error(msg): print(' - ERROR! ' + msg, file=sys.stderr) @@ -88,7 +90,7 @@ def check_switch_conf(sw_conf, workdir): raise ConfException("file does not exist %s" % real_path) -def program_switch(addr, device_id, sw_conf_file, workdir, proto_dump_fpath): +def program_switch(addr, device_id, sw_conf_file, workdir, proto_dump_fpath, runtime_json): sw_conf = json_load_byteified(sw_conf_file) try: check_switch_conf(sw_conf=sw_conf, workdir=workdir) @@ -126,6 +128,7 @@ def program_switch(addr, device_id, sw_conf_file, workdir, proto_dump_fpath): info("Inserting %d table entries..." % len(table_entries)) for entry in table_entries: info(tableEntryToString(entry)) + validateTableEntry(entry, p4info_helper, runtime_json) insertTableEntry(sw, entry, p4info_helper) if 'multicast_group_entries' in sw_conf: @@ -146,6 +149,26 @@ def program_switch(addr, device_id, sw_conf_file, workdir, proto_dump_fpath): sw.shutdown() +def validateTableEntry(flow, p4info_helper, runtime_json): + table_name = flow['table'] + match_fields = flow.get('match') # None if not found + priority = flow.get('priority') # None if not found + match_types_with_priority = [ + p4info_pb2.MatchField.TERNARY, + p4info_pb2.MatchField.RANGE + ] + if match_fields is not None and (priority is None or priority == 0): + for match_field_name, _ in match_fields.items(): + p4info_match = p4info_helper.get_match_field( + table_name, match_field_name) + match_type = p4info_match.match_type + if match_type in match_types_with_priority: + raise AssertionError( + "non-zero 'priority' field is required for all entries for table {} in {}" + .format(table_name, runtime_json) + ) + + def insertTableEntry(sw, flow, p4info_helper): table_name = flow['table'] match_fields = flow.get('match') # None if not found diff --git a/utils/run_exercise.py b/utils/run_exercise.py index 9a7b2b8..42886d6 100755 --- a/utils/run_exercise.py +++ b/utils/run_exercise.py @@ -273,7 +273,9 @@ class ExerciseRunner: device_id=device_id, sw_conf_file=sw_conf_file, workdir=os.getcwd(), - proto_dump_fpath=outfile) + proto_dump_fpath=outfile, + runtime_json=runtime_json + ) def program_switch_cli(self, sw_name, sw_dict): """ This method will start up the CLI and use the contents of the